feat: contextually type empty mutable slice literals
This commit is contained in:
@@ -1828,6 +1828,102 @@ immutable_pointer_and_slice_bindings_preserve_mutable_pointees :: proc(t: ^testi
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
fresh_empty_literals_initialize_mutable_slices_and_grow :: proc(t: ^testing.T) {
|
||||
directory := "/tmp/brolang-test-contextual-empty-slices"
|
||||
main_path := "/tmp/brolang-test-contextual-empty-slices/main.bro"
|
||||
output := "/tmp/brolang-test-contextual-empty-slices-output"
|
||||
text := `mem :: import "@std/mem"
|
||||
Item :: struct { value i32 }
|
||||
Views :: struct { integers []mut i32, records []mut Item }
|
||||
integers func(values []mut i32) usize { return values.len }
|
||||
records func(values []mut Item) usize { return values.len }
|
||||
generic func($T type, values []mut T, _ T) usize { return values.len }
|
||||
main func() i32 {
|
||||
numbers []mut i32 := &[]
|
||||
items []mut Item := &[]
|
||||
views Views := {integers = &[], records = &[]}
|
||||
if numbers.len != 0 or items.len != 0 { return 1 }
|
||||
if integers(&[]) != 0 or records(&[]) != 0 { return 2 }
|
||||
if views.integers.len != 0 or views.records.len != 0 { return 3 }
|
||||
integer i32 := 7
|
||||
item Item := {value = 9}
|
||||
if generic(&[], integer) != 0 or generic(&[], item) != 0 { return 7 }
|
||||
numbers = mem.realloc(mem.c_allocator, numbers, 2) catch |_| { return 4 }
|
||||
defer mem.free(mem.c_allocator, numbers)
|
||||
items = mem.realloc(mem.c_allocator, items, 1) catch |_| { return 5 }
|
||||
defer mem.free(mem.c_allocator, items)
|
||||
numbers[0] = 17
|
||||
numbers[1] = 25
|
||||
items[0] = {value = numbers[0] + numbers[1]}
|
||||
if numbers.len != 2 or items.len != 1 or items[0].value != 42 { return 6 }
|
||||
return 0
|
||||
}
|
||||
`
|
||||
_ = os2.remove_all(directory)
|
||||
defer _ = os2.remove_all(directory)
|
||||
defer _ = os.remove(output)
|
||||
testing.expect(t, os.make_directory(directory) == nil)
|
||||
testing.expect(t, os.write_entire_file(main_path, transmute([]byte)text))
|
||||
testing.expect_value(t, compiler_core.compile_package(
|
||||
directory, output, nil, target.DEFAULT, cimport.Options{}, ".",
|
||||
), 0)
|
||||
state := run_executable(output)
|
||||
testing.expect_value(t, state.exit_code, 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
empty_literal_mutability_does_not_weaken_readonly_or_sentinel_rules :: proc(t: ^testing.T) {
|
||||
cases := [?]string {
|
||||
`main func() void {
|
||||
values [0]i32 := []
|
||||
view []mut i32 := &values
|
||||
_ = view
|
||||
}
|
||||
`,
|
||||
`main func() void {
|
||||
view []mut i32 := &[1]
|
||||
_ = view
|
||||
}
|
||||
`,
|
||||
`main func() void {
|
||||
readonly []i32 := &[]
|
||||
view []mut i32 := readonly
|
||||
_ = view
|
||||
}
|
||||
`,
|
||||
`main func() void {
|
||||
view [;0]i32 := &[]
|
||||
_ = view
|
||||
}
|
||||
`,
|
||||
`main func() void {
|
||||
view [;0]mut i32 := &[]
|
||||
_ = view
|
||||
}
|
||||
`,
|
||||
}
|
||||
for text in cases {
|
||||
source_file := source.Source{path="invalid_empty_slice.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
defer delete(stream.items)
|
||||
ast_module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&ast_module)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
defer hir.destroy_module(&hir_module)
|
||||
found_conversion := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found_conversion = found_conversion ||
|
||||
strings.contains(diagnostic.message, "cannot implicitly convert")
|
||||
}
|
||||
testing.expect(t, found_conversion, text)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
many_item_pointer_slices_compile_and_run :: proc(t: ^testing.T) {
|
||||
directory := "/tmp/brolang-test-pointer-slices"
|
||||
|
||||
Reference in New Issue
Block a user