diff --git a/releasenotes.md b/releasenotes.md index eface0d6d..10310af6c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -21,6 +21,7 @@ - Create optional with `~` instead of `?`. `return io::EOF?;` becomes `return io::EOF~`. - Deprecated use of `?` to create optional. - Make `foo.$abc` implicitly mean `foo.eval("$abc")`. +- Deprecating multi-level array length inference. `int[*][*]` is deprecated and will be removed 0.8.0. ### Fixes - Regression with npot vector in struct triggering an assert #2219. diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 0514a5418..963090c8c 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -13,6 +13,7 @@ INLINE bool sema_resolve_vatype(SemaContext *context, TypeInfo *type_info); INLINE bool sema_resolve_evaltype(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind); INLINE bool sema_resolve_typefrom(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind); INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info); +static inline bool sema_check_ptr_type(SemaContext *context, TypeInfo *type_info, Type *inner); static int compare_function(Signature *sig, FunctionPrototype *proto); static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind) @@ -22,6 +23,8 @@ static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_in { return type_info_poison(type_info); } + if (!sema_check_ptr_type(context, type_info, type_info->pointer->type)) return type_info_poison(type_info); + // Construct the type after resolving the underlying type. type_info->type = type_get_ptr(type_info->pointer->type); type_info->resolve_status = RESOLVE_DONE; @@ -98,6 +101,10 @@ static inline bool sema_check_array_type(SemaContext *context, TypeInfo *origina { Type *distinct_base = type_flatten(base); + if (type_is_infer_type(distinct_base)) + { + SEMA_DEPRECATED(original_info, "Use of inferred inner types is not well supported and support will be removed in 0.8.0."); + } // We don't want to allow arrays with flexible members if (distinct_base->type_kind == TYPE_STRUCT) { @@ -475,6 +482,23 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) return true; } +static inline bool sema_check_ptr_type(SemaContext *context, TypeInfo *type_info, Type *inner) +{ + CanonicalType *type = inner->canonical; + switch (type->type_kind) + { + case CT_TYPES: + if (type_is_infer_type(type)) + { + SEMA_DEPRECATED(type_info, "Using an inferred type as a pointer is not supported and will be removed in 0.8.0."); + return true; + } + RETURN_SEMA_ERROR(type_info, "Pointers to %s are not supported.", type_quoted_error_string(inner)); + default: + return true; + } +} + static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind) { // Ok, already resolved. @@ -567,6 +591,7 @@ APPEND_QUALIFIERS: case TYPE_COMPRESSED_NONE: break; case TYPE_COMPRESSED_PTR: + if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info); type_info->type = type_get_ptr(type_info->type); break; case TYPE_COMPRESSED_SUB: @@ -577,9 +602,11 @@ APPEND_QUALIFIERS: type_info->type = type_get_ptr(type_info->type); break; case TYPE_COMPRESSED_PTRPTR: + if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info); type_info->type = type_get_ptr(type_get_ptr(type_info->type)); break; case TYPE_COMPRESSED_PTRSUB: + if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info); type_info->type = type_get_slice(type_get_ptr(type_info->type)); break; case TYPE_COMPRESSED_SUBSUB: diff --git a/test/test_suite/arrays/array_of_inferred_array.c3 b/test/test_suite/arrays/array_of_inferred_array.c3 index 2b9137250..7edd7a2a6 100644 --- a/test/test_suite/arrays/array_of_inferred_array.c3 +++ b/test/test_suite/arrays/array_of_inferred_array.c3 @@ -1,5 +1,5 @@ import std; -macro void test(int[*][6] a) +macro void test(int[2][6] a) { } fn void main() diff --git a/test/test_suite/arrays/complex_inferred_array.c3t b/test/test_suite/arrays/complex_inferred_array.c3t index 6f282cfc4..d42d8db94 100644 --- a/test/test_suite/arrays/complex_inferred_array.c3t +++ b/test/test_suite/arrays/complex_inferred_array.c3t @@ -3,8 +3,8 @@ module test; fn void main() { - int[*][*][2][*]? y = { {{{1}, {2}}, { {3}, {4}}}}; - int[*][*][2][*] x = { {{{1}, {2}}, { {3}, {4}}}}; + int[1][2][2][*]? y = { {{{1}, {2}}, { {3}, {4}}}}; + int[1][2][2][*] x = { {{{1}, {2}}, { {3}, {4}}}}; } /* #expect: test.ll diff --git a/test/test_suite/arrays/infer_multiple_err.c3 b/test/test_suite/arrays/infer_multiple_err.c3 index d2103ee0f..f53b135a9 100644 --- a/test/test_suite/arrays/infer_multiple_err.c3 +++ b/test/test_suite/arrays/infer_multiple_err.c3 @@ -2,17 +2,17 @@ fn void test1() { var $d = { {1}, {2, 3} }; - var $e = (int[*][*])$d; // #error: contains elements that have different lengths + var $e = (int[2][*])$d; // #error: This untyped list contained an element } fn void test2() { var $d = { {1}, {3}, {2} }; - var $e = (int[*][*])$d; + var $e = (int[1][*])$d; } fn void test3() { var $d = { {1}, {} }; - var $e = (int[*][*])$d; // #error: This untyped list contained an element of type + var $e = (int[1][*])$d; } diff --git a/test/test_suite/arrays/infer_previous_err.c3t b/test/test_suite/arrays/infer_previous_err.c3t index d81c1a330..288795cd1 100644 --- a/test/test_suite/arrays/infer_previous_err.c3t +++ b/test/test_suite/arrays/infer_previous_err.c3t @@ -2,8 +2,8 @@ module test; char[1][*] a = { [0] = { [0] = 1 } }; char[1][1] b = { [0] = { [0] = 1 } }; -char[*][*] c = { [0] = { [0] = 1 } }; -char[*][1] d = { [0] = { [0] = 1 } }; +char[2][*] c = { [0] = { [0] = 1 } }; +char[4][1] d = { [0] = { [0] = 1 } }; fn void main() { diff --git a/test/test_suite/arrays/inferred_array_slice_fail.c3 b/test/test_suite/arrays/inferred_array_slice_fail.c3 index b7ccef334..3d282ff2a 100644 --- a/test/test_suite/arrays/inferred_array_slice_fail.c3 +++ b/test/test_suite/arrays/inferred_array_slice_fail.c3 @@ -1,11 +1,11 @@ import std; -macro test(int[*][1] a) { +macro test(int[1][1] a) { var b = a; } fn int main() { int[][1] b; - test(b); // #error: It is not possible to cast 'int[][1]' to 'int[*][1]' + test(b); // #error: It is not possible to cast 'int[][1]' to 'int[1][1]' return 12; } \ No newline at end of file diff --git a/test/test_suite/arrays/inferred_subarray.c3 b/test/test_suite/arrays/inferred_subarray.c3 index b1c9a7399..d51bb6ee8 100644 --- a/test/test_suite/arrays/inferred_subarray.c3 +++ b/test/test_suite/arrays/inferred_subarray.c3 @@ -1,5 +1,4 @@ fn void main() { - int[*][*][] x = (int[2][1][]) { { { 1, 2 } } }; - int[*][*][*] y = (int[2][1][]) { { { 1, 2 } } }; + int[2][1][*] y = (int[2][1][]) { { { 1, 2 } } }; } diff --git a/test/test_suite/cast/cast_infer_slice.c3 b/test/test_suite/cast/cast_infer_slice.c3 index 480be6972..db9221b1e 100644 --- a/test/test_suite/cast/cast_infer_slice.c3 +++ b/test/test_suite/cast/cast_infer_slice.c3 @@ -2,6 +2,6 @@ import std; fn int main() { char[] a = "hello"; - char[*] b = *(char[*]*)&a; // #error: cannot be used to infer the length + char[*] b = *(char[5]*)a.ptr; return 0; } \ No newline at end of file diff --git a/test/test_suite/cast/cast_string_to_inferred_array.c3 b/test/test_suite/cast/cast_string_to_inferred_array.c3 deleted file mode 100644 index 0e5824fff..000000000 --- a/test/test_suite/cast/cast_string_to_inferred_array.c3 +++ /dev/null @@ -1,6 +0,0 @@ -import std; -fn void main() -{ - char[*]* x = "abc"; // #error: You cannot cast 'String' to 'char[*]*' - io::printn($typeof(x).nameof); -} \ No newline at end of file diff --git a/test/test_suite/cast/implicit_infer_len_cast.c3t b/test/test_suite/cast/implicit_infer_len_cast.c3t index 9392224b3..0e7538080 100644 --- a/test/test_suite/cast/implicit_infer_len_cast.c3t +++ b/test/test_suite/cast/implicit_infer_len_cast.c3t @@ -1,7 +1,7 @@ // #target: macos-x64 module test; -macro int test(int[*][*]* y) +macro int test(int[2][2]* y) { $typeof(*y) z = *y; return z[1][1]; @@ -11,7 +11,7 @@ fn void main() { int[2][*] x = { { 2, 3}, { 5, 6 }}; int[<2>][*] y = { { 1, 3 }}; - int[<*>][*] z = y; + int[<2>][*] z = y; int[<2>][1] w = z; int[<2>][] aa = { { 1, 3 }}; int[][*] bb = { { 1, 3 } }; diff --git a/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 b/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 index 040a4e36c..b4c796fcc 100644 --- a/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 +++ b/test/test_suite/expressions/casts/struct_cast_and_distinct.c3 @@ -27,6 +27,6 @@ struct Baz { int x; } fn void test4() { - Baz[2][*] x = { { { 2 } , { 3 } }, {{5}, {6} }}; - Bar[*][*] y = (Bar[2][2])x; + Baz[2][2] x = { { { 2 } , { 3 } }, {{5}, {6} }}; + Bar[2][2] y = (Bar[2][2])x; } diff --git a/test/test_suite/slices/slice_infer_inner_empty_err.c3 b/test/test_suite/slices/slice_infer_inner_empty_err.c3 deleted file mode 100644 index 1413db69c..000000000 --- a/test/test_suite/slices/slice_infer_inner_empty_err.c3 +++ /dev/null @@ -1,5 +0,0 @@ -fn int main() -{ - int [*][] y = { }; // #error: Inferring the slice inner type from an empty initializer is not possible - return 0; -} \ No newline at end of file diff --git a/test/unit/regression/vecpointer.c3 b/test/unit/regression/vecpointer.c3 index 0b7543fa7..319e5a5de 100644 --- a/test/unit/regression/vecpointer.c3 +++ b/test/unit/regression/vecpointer.c3 @@ -30,6 +30,6 @@ fn void pointer_add_sub_diff() assert(w == { -1, 2 }); int*[<2>] zz = y - (y - yy); assert(zz[0] == &a[1] && zz[1] == &a[2]); - int[*]*[<2>] g = (int[2]*[<2>]) { null, null }; - int[*]*[<*>] g2 = (int[2]*[<2>]) { null, null }; + int[2]*[<2>] g = { null, null }; + int[2]*[<2>] g2 = { null, null }; } \ No newline at end of file