style: compact inner groups and simple guard bodies
This commit is contained in:
+48
-123
@@ -360,9 +360,7 @@ check_elaborated proc(
|
||||
if (
|
||||
binding.kind == .declaration and !cells[i].assignment_value
|
||||
and !cells[usize(binding.data.declaration)].fixed and !has_narrowing(&state, id)
|
||||
) {
|
||||
join(&state, id, binding.data.declaration)
|
||||
}
|
||||
) join(&state, id, binding.data.declaration)
|
||||
}
|
||||
|
||||
# assignment inputs observe established declaration types, never contribute
|
||||
@@ -844,10 +842,8 @@ check_annotation proc(state @mut State, id ast.NodeId, allow_void bool) Type ! (
|
||||
element := try check_annotation(state, view.element, true)
|
||||
element_binding :: sema.binding(state.resolution, view.element)
|
||||
if (
|
||||
(
|
||||
element_binding.kind == .builtin
|
||||
and (element_binding.data.builtin == .int or element_binding.data.builtin == .float)
|
||||
)
|
||||
(element_binding.kind == .builtin
|
||||
and (element_binding.data.builtin == .int or element_binding.data.builtin == .float))
|
||||
or element.kind == .void or element.kind == .range
|
||||
) {
|
||||
element = invalid_type(try diagnostics.add(state.diagnostics, .invalid_array_element_type, ast.node_span(state.tree, view.element)))
|
||||
@@ -1233,9 +1229,7 @@ collect_expression proc(state @mut State, id ast.NodeId) void ! (mem.AllocError
|
||||
if (
|
||||
role != .parameter and role != .loop_capture and ast.decl_kind(tree, target) == .statement
|
||||
and type_syntax(ast.expr_kind(tree, ast.statement_decl(tree, target).initializer))
|
||||
) {
|
||||
state.cells[usize(id)].type = invalid_type(try diagnostics.add(state.diagnostics, .type_not_value, ast.node_span(tree, id)))
|
||||
}
|
||||
) state.cells[usize(id)].type = invalid_type(try diagnostics.add(state.diagnostics, .type_not_value, ast.node_span(tree, id)))
|
||||
}
|
||||
match binding.kind {
|
||||
.invalid: state.cells[usize(id)].type = invalid_type(binding.data.diagnostic)
|
||||
@@ -1464,13 +1458,11 @@ bool_equality proc(state @mut State, id ast.NodeId) bool {
|
||||
right :: group_type(state, expression.right)
|
||||
return (
|
||||
(expression.operator == .equal or expression.operator == .not_equal)
|
||||
and (
|
||||
(left.kind == .bool and right.kind == .bool)
|
||||
and ((left.kind == .bool and right.kind == .bool)
|
||||
or left.kind == .enumeration or right.kind == .enumeration
|
||||
or left.kind == .pointer or right.kind == .pointer
|
||||
or left.kind == .optional or right.kind == .optional
|
||||
or left.kind == .null or right.kind == .null
|
||||
)
|
||||
or left.kind == .null or right.kind == .null)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1739,10 +1731,8 @@ mutable_target proc(state @mut State, id ast.NodeId, allow_global bool) bool {
|
||||
pointer :: state.pointers.items[usize(base.pointer_type)]
|
||||
return (
|
||||
pointer.mutable
|
||||
and (
|
||||
pointer.many
|
||||
or (pointer.element.kind == .array and state.arrays.items[usize(pointer.element.array_type)].mutable)
|
||||
)
|
||||
and (pointer.many
|
||||
or (pointer.element.kind == .array and state.arrays.items[usize(pointer.element.array_type)].mutable))
|
||||
)
|
||||
}
|
||||
if (base.kind == .slice) return state.arrays.items[usize(base.array_type)].mutable
|
||||
@@ -1950,9 +1940,7 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
} else if (
|
||||
expected.kind != .void
|
||||
and !(expected.kind == .fallible and state.arrays.items[usize(expected.array_type)].element.kind == .void)
|
||||
) {
|
||||
try fail(state, id, .return_type_mismatch, statement.span)
|
||||
}
|
||||
) try fail(state, id, .return_type_mismatch, statement.span)
|
||||
}
|
||||
.expression: {
|
||||
match ast.expr_kind(tree, id) {
|
||||
@@ -1975,24 +1963,18 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
return
|
||||
}
|
||||
if (expression.operator == .unwrap) {
|
||||
if (state.types[usize(expression.operand)].kind != .optional and state.types[usize(expression.operand)].kind != .invalid) {
|
||||
try fail(state, id, .invalid_operand, expression.span)
|
||||
}
|
||||
if (state.types[usize(expression.operand)].kind != .optional and state.types[usize(expression.operand)].kind != .invalid) try fail(state, id, .invalid_operand, expression.span)
|
||||
return
|
||||
}
|
||||
if (expression.operator == .dereference) {
|
||||
if (
|
||||
state.types[usize(expression.operand)].kind != .invalid
|
||||
and state.types[usize(expression.operand)].kind != .pointer
|
||||
) {
|
||||
try fail(state, id, .invalid_dereference, expression.span)
|
||||
}
|
||||
) try fail(state, id, .invalid_dereference, expression.span)
|
||||
return
|
||||
}
|
||||
operand :: state.types[usize(expression.operand)]
|
||||
if (operand.kind != .invalid and (!numeric_kind(operand.kind) or unsigned_kind(operand.kind))) {
|
||||
try fail(state, id, .invalid_operand, ast.node_span(tree, id))
|
||||
}
|
||||
if (operand.kind != .invalid and (!numeric_kind(operand.kind) or unsigned_kind(operand.kind))) try fail(state, id, .invalid_operand, ast.node_span(tree, id))
|
||||
}
|
||||
.binary: {
|
||||
expression :: ast.binary_expr(tree, id)
|
||||
@@ -2005,9 +1987,7 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
right :: state.types[usize(expression.right)]
|
||||
if (left.kind == .invalid or right.kind == .invalid) return
|
||||
if (pointer_addition(state, id)) {
|
||||
if (right.kind != .usize or right.nominal != ast.NodeId(maxval!(u32))) {
|
||||
try fail(state, id, .invalid_operand, expression.span)
|
||||
}
|
||||
if (right.kind != .usize or right.nominal != ast.NodeId(maxval!(u32))) try fail(state, id, .invalid_operand, expression.span)
|
||||
return
|
||||
}
|
||||
if (
|
||||
@@ -2019,11 +1999,8 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
and (left.kind == .bool or left.kind == .enumeration or left.kind == .pointer)
|
||||
and (assignable_type(state, left, right) or assignable_type(state, right, left))
|
||||
) return
|
||||
if (!numeric_kind(left.kind) or !numeric_kind(right.kind) or !same_type(state, left, right)) {
|
||||
try fail(state, id, .invalid_operand, expression.span)
|
||||
} else if (expression.operator == .divide and left.kind != .float) {
|
||||
try fail(state, id, .integer_division, expression.span)
|
||||
}
|
||||
if (!numeric_kind(left.kind) or !numeric_kind(right.kind) or !same_type(state, left, right)) try fail(state, id, .invalid_operand, expression.span)
|
||||
else if (expression.operator == .divide and left.kind != .float) try fail(state, id, .integer_division, expression.span)
|
||||
}
|
||||
.range: {
|
||||
if (state.cells[usize(id)].match_pattern) return
|
||||
@@ -2032,12 +2009,8 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
end_type :: state.types[usize(expression.end)]
|
||||
family TypeKind :: if (integer_kind(start_type.kind)) start_type.kind
|
||||
else if (integer_kind(end_type.kind)) end_type.kind else .int
|
||||
if (start_type.kind != .invalid and (!integer_kind(start_type.kind) or start_type.kind != family)) {
|
||||
try fail(state, expression.start, .invalid_range_bound, ast.node_span(tree, expression.start))
|
||||
}
|
||||
if (end_type.kind != .invalid and (!integer_kind(end_type.kind) or end_type.kind != family)) {
|
||||
try fail(state, expression.end, .invalid_range_bound, ast.node_span(tree, expression.end))
|
||||
}
|
||||
if (start_type.kind != .invalid and (!integer_kind(start_type.kind) or start_type.kind != family)) try fail(state, expression.start, .invalid_range_bound, ast.node_span(tree, expression.start))
|
||||
if (end_type.kind != .invalid and (!integer_kind(end_type.kind) or end_type.kind != family)) try fail(state, expression.end, .invalid_range_bound, ast.node_span(tree, expression.end))
|
||||
}
|
||||
.array_literal: {
|
||||
actual :: state.types[usize(id)]
|
||||
@@ -2045,11 +2018,8 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
element :: state.arrays.items[usize(actual.array_type)].element
|
||||
for 0..ast.array_element_count(tree, id) |i| {
|
||||
child :: ast.array_element(tree, id, i)
|
||||
if (element.kind == .void or element.kind == .range) {
|
||||
try fail(state, child, .invalid_array_element_type, ast.node_span(tree, child))
|
||||
} else {
|
||||
try compatible(state, child, element)
|
||||
}
|
||||
if (element.kind == .void or element.kind == .range) try fail(state, child, .invalid_array_element_type, ast.node_span(tree, child))
|
||||
else try compatible(state, child, element)
|
||||
}
|
||||
if (array_cells(state, actual) == null) try fail(state, id, .array_size_overflow, ast.node_span(tree, id))
|
||||
}
|
||||
@@ -2057,9 +2027,7 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
actual :: state.types[usize(id)]
|
||||
if (actual.kind != .record) return
|
||||
descriptor := state.records.items[usize(actual.record_type)]
|
||||
if (state.variant_slots[usize(id)] != no_index and state.backings[usize(id)].kind == .record) {
|
||||
descriptor = state.records.items[usize(state.backings[usize(id)].record_type)]
|
||||
}
|
||||
if (state.variant_slots[usize(id)] != no_index and state.backings[usize(id)].kind == .record) descriptor = state.records.items[usize(state.backings[usize(id)].record_type)]
|
||||
fields :: descriptor.fields
|
||||
slot :: state.slots[usize(id)]
|
||||
if (slot == no_index) return
|
||||
@@ -2073,12 +2041,8 @@ validate proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | diagnost
|
||||
view :: ast.index_expr(tree, id)
|
||||
base :: state.types[usize(view.base)]
|
||||
index :: state.types[usize(view.index)]
|
||||
if (index.kind != .invalid and (index.kind != .usize or index.nominal != ast.NodeId(maxval!(u32)))) {
|
||||
try fail(state, view.index, .invalid_index_type, ast.node_span(tree, view.index))
|
||||
}
|
||||
if (base.kind != .invalid and !indexable_type(state, base)) {
|
||||
try fail(state, id, .not_indexable, ast.node_span(tree, view.base))
|
||||
}
|
||||
if (index.kind != .invalid and (index.kind != .usize or index.nominal != ast.NodeId(maxval!(u32)))) try fail(state, view.index, .invalid_index_type, ast.node_span(tree, view.index))
|
||||
if (base.kind != .invalid and !indexable_type(state, base)) try fail(state, id, .not_indexable, ast.node_span(tree, view.base))
|
||||
}
|
||||
.call: try validate_call(state, id)
|
||||
.builtin_call: _ = try infer_builtin(state, id, true)
|
||||
@@ -2116,13 +2080,9 @@ validate_call proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | dia
|
||||
backing :: immediate_backing(state, actual)
|
||||
if (
|
||||
actual.kind != .invalid
|
||||
and (
|
||||
!numeric_kind(backing.kind) and !allowed_enum
|
||||
or backing.nominal != ast.NodeId(maxval!(u32))
|
||||
)
|
||||
) {
|
||||
try fail(state, argument, .invalid_operand, ast.node_span(tree, argument))
|
||||
}
|
||||
and (!numeric_kind(backing.kind) and !allowed_enum
|
||||
or backing.nominal != ast.NodeId(maxval!(u32)))
|
||||
) try fail(state, argument, .invalid_operand, ast.node_span(tree, argument))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -2283,9 +2243,7 @@ intern_pointer proc(state @mut State, descriptor PointerType) Type ! mem.AllocEr
|
||||
if (
|
||||
existing.mutable == descriptor.mutable and existing.many == descriptor.many
|
||||
and same_type(state, existing.element, descriptor.element)
|
||||
) {
|
||||
return Type{ kind = .pointer, pointer_type = PointerId(i) }
|
||||
}
|
||||
) return Type{ kind = .pointer, pointer_type = PointerId(i) }
|
||||
}
|
||||
try arraylist.append(&state.pointers, descriptor)
|
||||
return Type{ kind = .pointer, pointer_type = PointerId(state.pointers.items.len - 1) }
|
||||
@@ -2304,9 +2262,7 @@ check_pointer_type proc(state @mut State, id ast.NodeId) Type ! (mem.AllocError
|
||||
or element.kind == .type_value
|
||||
or has_inferred_count(state, element)
|
||||
or (binding.kind == .builtin and (binding.data.builtin == .int or binding.data.builtin == .float))
|
||||
) {
|
||||
return invalid_type(try diagnostics.add(state.diagnostics, .invalid_pointer_type, ast.node_span(state.tree, id)))
|
||||
}
|
||||
) return invalid_type(try diagnostics.add(state.diagnostics, .invalid_pointer_type, ast.node_span(state.tree, id)))
|
||||
return try intern_pointer(state, PointerType{ element = element, mutable = view.mutable, many = view.many })
|
||||
}
|
||||
|
||||
@@ -2346,9 +2302,7 @@ intern_array proc(state @mut State, descriptor ArrayType) Type ! mem.AllocError
|
||||
existing.kind == descriptor.kind and existing.len == descriptor.len and existing.mutable == descriptor.mutable
|
||||
and same_sentinel(existing.sentinel, descriptor.sentinel) and same_type(state, existing.element, descriptor.element)
|
||||
and same_type(state, existing.error_type, descriptor.error_type)
|
||||
) {
|
||||
return Type{ kind = descriptor.kind, array_type = ArrayId(i) }
|
||||
}
|
||||
) return Type{ kind = descriptor.kind, array_type = ArrayId(i) }
|
||||
}
|
||||
try arraylist.append(&state.arrays, descriptor)
|
||||
return Type{ kind = descriptor.kind, array_type = ArrayId(state.arrays.items.len - 1) }
|
||||
@@ -3074,9 +3028,7 @@ apply_contexts proc(state @mut State, assignment_values, early bool) void ! (mem
|
||||
if (
|
||||
ast.call_arg_count(tree, id) == 1
|
||||
and (backing.nominal != ast.NodeId(maxval!(u32)) or !numeric_kind(backing.kind))
|
||||
) {
|
||||
try context_demand(state, ast.call_arg(tree, id, 0), backing, .type_mismatch, early)
|
||||
}
|
||||
) try context_demand(state, ast.call_arg(tree, id, 0), backing, .type_mismatch, early)
|
||||
continue
|
||||
}
|
||||
if (conversion_kind(state, id) != .none) {
|
||||
@@ -3165,9 +3117,7 @@ prepare_ranges proc(state @mut State, assignment_values, constrain bool) void !
|
||||
if (
|
||||
binding.kind == .declaration and state.cells[usize(binding.data.declaration)].role == .loop_capture
|
||||
and !has_narrowing(state, id)
|
||||
) {
|
||||
seed(state, id, group_type(state, binding.data.declaration))
|
||||
}
|
||||
) seed(state, id, group_type(state, binding.data.declaration))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3230,9 +3180,7 @@ specialize_annotations proc(state @mut State) void ! (mem.AllocError | diagnosti
|
||||
if (
|
||||
binding.kind == .declaration and state.cells[usize(binding.data.declaration)].fixed
|
||||
and !has_narrowing(state, id)
|
||||
) {
|
||||
seed(state, id, state.cells[usize(binding.data.declaration)].type)
|
||||
}
|
||||
) seed(state, id, state.cells[usize(binding.data.declaration)].type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3742,9 +3690,7 @@ check_union proc(state @mut State, id ast.NodeId, nominal bool) Type ! (mem.Allo
|
||||
if (
|
||||
type.kind == .none or type.kind == .range or type.kind == .type_value or field.value != null
|
||||
or (type.kind == .void and tag.kind == .none and !view.auto_tag)
|
||||
) {
|
||||
return invalid_type(try diagnostics.add(state.diagnostics, .invalid_record_field_type, field.span))
|
||||
}
|
||||
) return invalid_type(try diagnostics.add(state.diagnostics, .invalid_record_field_type, field.span))
|
||||
if (field.name == null or named_field(state.tree, fields[0..i], field.name?) != no_index) {
|
||||
return invalid_type(try diagnostics.add(state.diagnostics, .duplicate_field, field.span))
|
||||
}
|
||||
@@ -4201,21 +4147,13 @@ validate_match proc(state @mut State, id ast.NodeId) void ! (mem.AllocError | di
|
||||
current :: try pattern_interval(state, pattern, key)
|
||||
if (current) |interval| {
|
||||
if (
|
||||
(
|
||||
interval.real and (
|
||||
interval.real_low > interval.real_high
|
||||
or (!interval.inclusive and interval.real_low == interval.real_high)
|
||||
)
|
||||
)
|
||||
or (
|
||||
!interval.real and (
|
||||
constant_order(interval.low, interval.high) > 0
|
||||
or (!interval.inclusive and constant_order(interval.low, interval.high) == 0)
|
||||
)
|
||||
)
|
||||
) {
|
||||
try fail(state, id, .invalid_match_pattern, ast.node_span(state.tree, pattern))
|
||||
}
|
||||
(interval.real and (
|
||||
interval.real_low > interval.real_high
|
||||
or (!interval.inclusive and interval.real_low == interval.real_high)))
|
||||
or (!interval.real and (
|
||||
constant_order(interval.low, interval.high) > 0
|
||||
or (!interval.inclusive and constant_order(interval.low, interval.high) == 0)))
|
||||
) try fail(state, id, .invalid_match_pattern, ast.node_span(state.tree, pattern))
|
||||
if (key.kind == .bool) {
|
||||
if (interval.low.magnitude == 0) seen_false = true else seen_true = true
|
||||
}
|
||||
@@ -4348,20 +4286,14 @@ check_fallible_type proc(state @mut State, id ast.NodeId) Type ! (mem.AllocError
|
||||
if (failure.kind == .invalid) return failure
|
||||
valid_error :: (
|
||||
failure.kind == .enumeration
|
||||
or (
|
||||
failure.kind == .record
|
||||
and (
|
||||
!state.records.items[usize(failure.record_type)].is_union
|
||||
or state.records.items[usize(failure.record_type)].tag_type.kind == .enumeration
|
||||
)
|
||||
)
|
||||
or (failure.kind == .record
|
||||
and (!state.records.items[usize(failure.record_type)].is_union
|
||||
or state.records.items[usize(failure.record_type)].tag_type.kind == .enumeration))
|
||||
)
|
||||
if (
|
||||
!valid_error or success.kind == .none or success.kind == .range or success.kind == .type_value
|
||||
or success.kind == .anyopaque or has_inferred_count(state, success)
|
||||
) {
|
||||
return invalid_type(try diagnostics.add(state.diagnostics, .invalid_fallible_type, ast.node_span(state.tree, id)))
|
||||
}
|
||||
) return invalid_type(try diagnostics.add(state.diagnostics, .invalid_fallible_type, ast.node_span(state.tree, id)))
|
||||
type :: try intern_array(state, ArrayType{ kind = .fallible, element = success, error_type = failure })
|
||||
state.cells[usize(id)].type = type
|
||||
return type
|
||||
@@ -4536,14 +4468,10 @@ validate_fallible_expression proc(state @mut State, id ast.NodeId) void ! (mem.A
|
||||
if (catching) {
|
||||
expression :: ast.catch_expr(state.tree, id)
|
||||
if (expression.handler_is_block) {
|
||||
if (descriptor.element.kind != .void and block_falls_through(state, expression.handler)) {
|
||||
try fail(state, expression.handler, .catch_type_mismatch, ast.node_span(state.tree, expression.handler))
|
||||
}
|
||||
if (descriptor.element.kind != .void and block_falls_through(state, expression.handler)) try fail(state, expression.handler, .catch_type_mismatch, ast.node_span(state.tree, expression.handler))
|
||||
} else {
|
||||
actual :: state.types[usize(expression.handler)]
|
||||
if (actual.kind != .invalid and !assignable_value(state, expression.handler, actual, descriptor.element)) {
|
||||
try fail(state, expression.handler, .catch_type_mismatch, ast.node_span(state.tree, expression.handler))
|
||||
}
|
||||
if (actual.kind != .invalid and !assignable_value(state, expression.handler, actual, descriptor.element)) try fail(state, expression.handler, .catch_type_mismatch, ast.node_span(state.tree, expression.handler))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -4558,18 +4486,15 @@ validate_fallible_expression proc(state @mut State, id ast.NodeId) void ! (mem.A
|
||||
}
|
||||
result :: state.types[usize(annotation)]
|
||||
if (result.kind == .invalid) return
|
||||
if (result.kind != .fallible) {
|
||||
try fail(state, id, .try_outside_fallible, ast.node_span(state.tree, id))
|
||||
} else if (
|
||||
if (result.kind != .fallible) try fail(state, id, .try_outside_fallible, ast.node_span(state.tree, id))
|
||||
else if (
|
||||
!error_subset(
|
||||
state.records.items,
|
||||
state.enums.items,
|
||||
descriptor.error_type,
|
||||
state.arrays.items[usize(result.array_type)].error_type,
|
||||
)
|
||||
) {
|
||||
try fail(state, id, .incompatible_propagated_error, ast.node_span(state.tree, id))
|
||||
}
|
||||
) try fail(state, id, .incompatible_propagated_error, ast.node_span(state.tree, id))
|
||||
}
|
||||
|
||||
@hide:file
|
||||
|
||||
@@ -168,11 +168,8 @@ rejects_fixed_family_conversion_integer_division_and_conflicting_demands test {
|
||||
for conflicts |declaration| {
|
||||
try testing.expect_equal(TypeKind.invalid, type_of(&result, declaration).kind)
|
||||
diagnostic :: type_of(&result, declaration).diagnostic
|
||||
if (diagnostics.get(&diagnostic_store, diagnostic)) |error| {
|
||||
try testing.expect_equal(diagnostics.Code.type_mismatch, error.code)
|
||||
} else {
|
||||
return .expectation_failed
|
||||
}
|
||||
if (diagnostics.get(&diagnostic_store, diagnostic)) |error| try testing.expect_equal(diagnostics.Code.type_mismatch, error.code)
|
||||
else return .expectation_failed
|
||||
try testing.expect_equal(diagnostic, type_of(&result, ast.statement_decl(&tree, declaration).initializer).diagnostic)
|
||||
}
|
||||
conflict_uses [4]usize :: [8, 9, 11, 12]
|
||||
@@ -294,11 +291,8 @@ separates_type_annotations_from_values_and_restricts_void_storage test {
|
||||
defer deinit(&result)
|
||||
|
||||
bad :: ast.statement_decl(&tree, ast.package_decl(&tree, 1))
|
||||
if (bad.type) |annotation| {
|
||||
_ = try expect_error(&result, &diagnostic_store, annotation, .expected_type, ast.node_span(&tree, annotation))
|
||||
} else {
|
||||
return .expectation_failed
|
||||
}
|
||||
if (bad.type) |annotation| _ = try expect_error(&result, &diagnostic_store, annotation, .expected_type, ast.node_span(&tree, annotation))
|
||||
else return .expectation_failed
|
||||
_ = try expect_error(&result, &diagnostic_store, bad.initializer, .invalid_operand, ast.node_span(&tree, bad.initializer))
|
||||
builtin :: ast.statement_decl(&tree, ast.package_decl(&tree, 2)).initializer
|
||||
_ = try expect_error(&result, &diagnostic_store, builtin, .type_not_value, ast.node_span(&tree, builtin))
|
||||
@@ -322,11 +316,8 @@ separates_type_annotations_from_values_and_restricts_void_storage test {
|
||||
try testing.expect_equal(void_error, type_of(&result, void_b).diagnostic)
|
||||
try expect_kind(&result, ast.function_decl(&tree, void_function).return_type, .void)
|
||||
storage :: ast.statement_decl(&tree, ast.package_decl(&tree, 5))
|
||||
if (storage.type) |annotation| {
|
||||
_ = try expect_error(&result, &diagnostic_store, annotation, .invalid_void_type, ast.node_span(&tree, annotation))
|
||||
} else {
|
||||
return .expectation_failed
|
||||
}
|
||||
if (storage.type) |annotation| _ = try expect_error(&result, &diagnostic_store, annotation, .invalid_void_type, ast.node_span(&tree, annotation))
|
||||
else return .expectation_failed
|
||||
holder :: ast.statement_decl(&tree, ast.package_decl(&tree, 8)).initializer
|
||||
_ = try expect_error(&result, &diagnostic_store, holder, .type_mismatch, ast.node_span(&tree, holder))
|
||||
operand :: ast.statement_decl(&tree, ast.package_decl(&tree, 9)).initializer
|
||||
@@ -677,11 +668,8 @@ returns_supply_numeric_context_and_resolve_forward_local_and_parameter_names tes
|
||||
}
|
||||
identity :: ast.package_decl(&tree, 1)
|
||||
identity_body :: ast.function_decl(&tree, identity).body
|
||||
if (ast.return_stmt(&tree, ast.block_statement(&tree, identity_body, 0)).value) |value| {
|
||||
try testing.expect_equal(ast.function_param(&tree, identity, 0), sema.binding(&resolution, value).data.declaration)
|
||||
} else {
|
||||
return .expectation_failed
|
||||
}
|
||||
if (ast.return_stmt(&tree, ast.block_statement(&tree, identity_body, 0)).value) |value| try testing.expect_equal(ast.function_param(&tree, identity, 0), sema.binding(&resolution, value).data.declaration)
|
||||
else return .expectation_failed
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
@@ -1429,11 +1417,8 @@ logical_operand_errors_are_independent_and_skipped_rhs_preserves_bool test {
|
||||
try expect_kind(&result, loop.condition, .bool)
|
||||
returned :: ast.block_statement(&tree, body, 6)
|
||||
try expect_kind(&result, returned, .void)
|
||||
if (ast.return_stmt(&tree, returned).value) |value| {
|
||||
try expect_kind(&result, value, .bool)
|
||||
} else {
|
||||
return .expectation_failed
|
||||
}
|
||||
if (ast.return_stmt(&tree, returned).value) |value| try expect_kind(&result, value, .bool)
|
||||
else return .expectation_failed
|
||||
try testing.expect_equal(7, code_count(&diagnostic_store, .unknown_name))
|
||||
try testing.expect_equal(8, code_count(&diagnostic_store, .invalid_operand))
|
||||
try testing.expect_equal(15, diagnostics.count(&diagnostic_store))
|
||||
@@ -2271,9 +2256,7 @@ nested_array_numeric_context_flows_through_index_children_before_defaults test {
|
||||
for usize(1)..usize(4) |i| {
|
||||
element_kind TypeKind :: if (i == 2) .float else .array
|
||||
type :: try expect_array(result, ast.package_decl(tree, i), 2, false, element_kind)
|
||||
if (type.element.kind == .array) {
|
||||
try testing.expect_equal(TypeKind.float, array_type(result, type.element.array_type).element.kind)
|
||||
}
|
||||
if (type.element.kind == .array) try testing.expect_equal(TypeKind.float, array_type(result, type.element.array_type).element.kind)
|
||||
}
|
||||
matrix :: ast.statement_decl(tree, ast.package_decl(tree, 1)).initializer
|
||||
for 0..ast.array_element_count(tree, matrix) |i| {
|
||||
|
||||
+6
-18
@@ -349,9 +349,7 @@ resolve_function proc(
|
||||
for (0..ast.function_param_count(tree, id)) |i| {
|
||||
parameter :: ast.function_param(tree, id, i)
|
||||
try resolve_expr(state, &signature, ast.param(tree, parameter).type)
|
||||
if (ast.param(tree, parameter).comptime) {
|
||||
try predeclare(state, &signature, parameter, ast.param(tree, parameter).name)
|
||||
}
|
||||
if (ast.param(tree, parameter).comptime) try predeclare(state, &signature, parameter, ast.param(tree, parameter).name)
|
||||
}
|
||||
try resolve_expr(state, &signature, function.return_type)
|
||||
scope := Scope{
|
||||
@@ -381,9 +379,7 @@ resolve_block proc(state @mut State, scope @mut Scope, id ast.NodeId) void ! (me
|
||||
tree :: state.tree
|
||||
for (0..ast.block_statement_count(tree, id)) |i| {
|
||||
statement :: ast.block_statement(tree, id, i)
|
||||
if ast.stmt_kind(tree, statement) == .declaration {
|
||||
try predeclare(state, scope, statement, ast.statement_decl(tree, statement).name)
|
||||
}
|
||||
if (ast.stmt_kind(tree, statement) == .declaration) try predeclare(state, scope, statement, ast.statement_decl(tree, statement).name)
|
||||
}
|
||||
for (0..ast.block_statement_count(tree, id)) |i| {
|
||||
statement :: ast.block_statement(tree, id, i)
|
||||
@@ -423,12 +419,8 @@ resolve_block proc(state @mut State, scope @mut Scope, id ast.NodeId) void ! (me
|
||||
parent = scope,
|
||||
}
|
||||
defer hashmap.deinit(&body_scope.names)
|
||||
if (loop.capture) |capture| {
|
||||
try predeclare(state, &body_scope, capture, ast.node_span(tree, capture))
|
||||
}
|
||||
if (loop.index) |index| {
|
||||
try predeclare(state, &body_scope, index, ast.node_span(tree, index))
|
||||
}
|
||||
if (loop.capture) |capture| try predeclare(state, &body_scope, capture, ast.node_span(tree, capture))
|
||||
if (loop.index) |index| try predeclare(state, &body_scope, index, ast.node_span(tree, index))
|
||||
try resolve_block(state, &body_scope, loop.body)
|
||||
}
|
||||
.invalid: resolve_invalid(state, statement)
|
||||
@@ -451,9 +443,7 @@ resolve_statement_decl proc(
|
||||
id ast.NodeId,
|
||||
) void ! (mem.AllocError | diagnostics.CapacityError) {
|
||||
declaration :: ast.statement_decl(state.tree, id)
|
||||
if (ast.expr_kind(state.tree, declaration.initializer) == .alias_expr) {
|
||||
state.aliases[usize(id)] = ast.type_operand(state.tree, declaration.initializer)
|
||||
}
|
||||
if (ast.expr_kind(state.tree, declaration.initializer) == .alias_expr) state.aliases[usize(id)] = ast.type_operand(state.tree, declaration.initializer)
|
||||
if (declaration.type) |type| try resolve_expr(state, scope, type)
|
||||
try resolve_expr(state, scope, declaration.initializer)
|
||||
}
|
||||
@@ -562,9 +552,7 @@ resolve_expr proc(
|
||||
try resolve_expr(state, scope, expression.operand)
|
||||
handler_scope := Scope{ names = hashmap.init(state.allocator), parent = scope }
|
||||
defer hashmap.deinit(&handler_scope.names)
|
||||
if (expression.capture) |capture| {
|
||||
try predeclare(state, &handler_scope, capture, ast.node_span(tree, capture))
|
||||
}
|
||||
if (expression.capture) |capture| try predeclare(state, &handler_scope, capture, ast.node_span(tree, capture))
|
||||
if (expression.handler_is_block) try resolve_block(state, &handler_scope, expression.handler)
|
||||
else try resolve_expr(state, &handler_scope, expression.handler)
|
||||
}
|
||||
|
||||
@@ -581,9 +581,8 @@ range_captures_preserve_duplicate_builtin_and_discard_errors test {
|
||||
} else return .expectation_failed
|
||||
}
|
||||
indexed :: ast.for_stmt(&tree, ast.block_statement(&tree, body, 3))
|
||||
if (indexed.index) |index| {
|
||||
try testing.expect_equal(BindingKind.invalid, binding(&resolution, index).kind)
|
||||
} else return .expectation_failed
|
||||
if (indexed.index) |index| try testing.expect_equal(BindingKind.invalid, binding(&resolution, index).kind)
|
||||
else return .expectation_failed
|
||||
if (indexed.capture) |capture| {
|
||||
reference :: ast.statement_expr(&tree, ast.block_statement(&tree, indexed.body, 0))
|
||||
try testing.expect_equal(capture, binding(&resolution, reference).data.declaration)
|
||||
|
||||
@@ -528,11 +528,8 @@ specialize_call proc(state @mut State, call, function ast.NodeId) void ! Error {
|
||||
}
|
||||
callee :: try reference(state, call, target)
|
||||
replacement := no_node
|
||||
if (state.instances.items[instance].type != no_node) {
|
||||
replacement = try ast.add_type_operand(state.builder, ast.node_span(&state.tree, call), callee, true)
|
||||
} else {
|
||||
replacement = try ast.add_call(state.builder, ast.node_span(&state.tree, call), callee, runtime_arguments.items)
|
||||
}
|
||||
if (state.instances.items[instance].type != no_node) replacement = try ast.add_type_operand(state.builder, ast.node_span(&state.tree, call), callee, true)
|
||||
else replacement = try ast.add_call(state.builder, ast.node_span(&state.tree, call), callee, runtime_arguments.items)
|
||||
try replace(state, call, replacement)
|
||||
try refresh(state)
|
||||
}
|
||||
@@ -1554,13 +1551,10 @@ evaluate proc(state @mut State, id ast.NodeId) Value ! Error {
|
||||
.unary: {
|
||||
view :: ast.unary_expr(&state.tree, id)
|
||||
value := try evaluate(state, view.operand)
|
||||
if (view.operator == .negate and value.kind == .integer) {
|
||||
value.negative = value.magnitude != 0 and !value.negative
|
||||
} else if (view.operator == .negate and value.kind == .real) {
|
||||
value.magnitude = value.magnitude xor (u64(1) << 63)
|
||||
} else if (view.operator == .logical_not and value.kind == .boolean) {
|
||||
value.boolean = !value.boolean
|
||||
} else return Value{}
|
||||
if (view.operator == .negate and value.kind == .integer) value.negative = value.magnitude != 0 and !value.negative
|
||||
else if (view.operator == .negate and value.kind == .real) value.magnitude = value.magnitude xor (u64(1) << 63)
|
||||
else if (view.operator == .logical_not and value.kind == .boolean) value.boolean = !value.boolean
|
||||
else return Value{}
|
||||
value.node = id
|
||||
return value
|
||||
}
|
||||
@@ -1642,9 +1636,7 @@ evaluate_binary proc(state @mut State, id ast.NodeId) Value ! Error {
|
||||
if (left.magnitude > maxval!(u64) - right.magnitude) return Value{}
|
||||
return try integer_value(state, id, left.magnitude + right.magnitude, left.negative, annotation)
|
||||
}
|
||||
if (left.magnitude < right.magnitude) {
|
||||
return try integer_value(state, id, right.magnitude - left.magnitude, right.negative, annotation)
|
||||
}
|
||||
if (left.magnitude < right.magnitude) return try integer_value(state, id, right.magnitude - left.magnitude, right.negative, annotation)
|
||||
return try integer_value(state, id, left.magnitude - right.magnitude,
|
||||
left.magnitude != right.magnitude and left.negative, annotation)
|
||||
}
|
||||
@@ -1666,9 +1658,7 @@ same_type proc(state @mut State, left, right ast.NodeId) bool ! Error {
|
||||
if (a == b) return true
|
||||
x :: binding(state, a)
|
||||
y :: binding(state, b)
|
||||
if (x.kind == .builtin or y.kind == .builtin) {
|
||||
return x.kind == .builtin and y.kind == .builtin and builtin_identity(x.data.builtin) == builtin_identity(y.data.builtin)
|
||||
}
|
||||
if (x.kind == .builtin or y.kind == .builtin) return x.kind == .builtin and y.kind == .builtin and builtin_identity(x.data.builtin) == builtin_identity(y.data.builtin)
|
||||
kind :: ast.expr_kind(&state.tree, a)
|
||||
if (kind == .sum_type or ast.expr_kind(&state.tree, b) == .sum_type)
|
||||
return try type_subset(state, a, b) and try type_subset(state, b, a)
|
||||
@@ -1908,9 +1898,7 @@ expression_type proc(state @mut State, id ast.NodeId, depth usize) ast.NodeId !
|
||||
callee :: ast.call_expr(&state.tree, id).callee
|
||||
destination :: binding(state, callee)
|
||||
if (destination.kind == .builtin) return callee
|
||||
if (destination.kind == .declaration and ast.node_class(&state.tree, destination.data.declaration) == .function) {
|
||||
return try canonical_type(state, ast.function_decl(&state.tree, destination.data.declaration).return_type)
|
||||
}
|
||||
if (destination.kind == .declaration and ast.node_class(&state.tree, destination.data.declaration) == .function) return try canonical_type(state, ast.function_decl(&state.tree, destination.data.declaration).return_type)
|
||||
signature :: try expression_type(state, callee, depth + 1)
|
||||
if (signature != no_node and ast.expr_kind(&state.tree, signature) == .function_type)
|
||||
return try canonical_type(state, ast.callable_result(&state.tree, signature))
|
||||
|
||||
Reference in New Issue
Block a user