diff --git a/lib/std/collections/bitset.c3 b/lib/std/collections/bitset.c3 index 99a58d875..c6dfff35c 100644 --- a/lib/std/collections/bitset.c3 +++ b/lib/std/collections/bitset.c3 @@ -75,7 +75,7 @@ import std::collections::list; const BITS = Type.sizeof * 8; -def GrowableBitSetList = List(); +def GrowableBitSetList = List<[Type]>; struct GrowableBitSet { diff --git a/lib/std/collections/object.c3 b/lib/std/collections/object.c3 index f14dc87d0..b9cb8708a 100644 --- a/lib/std/collections/object.c3 +++ b/lib/std/collections/object.c3 @@ -462,7 +462,7 @@ fn Object* Object.get_or_create_obj(&self, String key) return container; } -def ObjectInternalMap = HashMap() @private; -def ObjectInternalList = List() @private; -def ObjectInternalMapEntry = Entry() @private; +def ObjectInternalMap = HashMap<[String, Object*]> @private; +def ObjectInternalList = List<[Object*]> @private; +def ObjectInternalMapEntry = Entry<[String, Object*]> @private; diff --git a/lib/std/collections/priorityqueue.c3 b/lib/std/collections/priorityqueue.c3 index e83a00cb9..6550f3cfe 100644 --- a/lib/std/collections/priorityqueue.c3 +++ b/lib/std/collections/priorityqueue.c3 @@ -23,13 +23,13 @@ module std::collections::priorityqueue(); import std::collections::priorityqueue::private; -distinct PriorityQueue = inline PrivatePriorityQueue(); -distinct PriorityQueueMax = inline PrivatePriorityQueue(); +distinct PriorityQueue = inline PrivatePriorityQueue<[Type, false]>; +distinct PriorityQueueMax = inline PrivatePriorityQueue<[Type, true]>; module std::collections::priorityqueue::private(); import std::collections::list, std::io; -def Heap = List(); +def Heap = List<[Type]>; struct PrivatePriorityQueue (Printable) { diff --git a/lib/std/core/allocators/tracking_allocator.c3 b/lib/std/core/allocators/tracking_allocator.c3 index ef831be82..67c336bde 100644 --- a/lib/std/core/allocators/tracking_allocator.c3 +++ b/lib/std/core/allocators/tracking_allocator.c3 @@ -13,7 +13,7 @@ struct Allocation void*[MAX_BACKTRACE] backtrace; } -def AllocMap = HashMap(); +def AllocMap = HashMap<[uptr, Allocation]>; // A simple tracking allocator. // It tracks allocations using a hash map but diff --git a/lib/std/core/array.c3 b/lib/std/core/array.c3 index abb808e34..8631f7b1e 100644 --- a/lib/std/core/array.c3 +++ b/lib/std/core/array.c3 @@ -26,7 +26,7 @@ macro slice2d(array_ptr, x = 0, xlen = 0, y = 0, ylen = 0) if (xlen < 1) xlen = $typeof((*array_ptr)[0]).len + xlen; if (ylen < 1) ylen = $typeof((*array_ptr)).len + ylen; var $ElementType = $typeof((*array_ptr)[0][0]); - return Slice2d(<$ElementType>) { ($ElementType*)array_ptr, $typeof((*array_ptr)[0]).len, y, ylen, x, xlen }; + return Slice2d<[$ElementType]> { ($ElementType*)array_ptr, $typeof((*array_ptr)[0]).len, y, ylen, x, xlen }; } diff --git a/lib/std/hash/md5.c3 b/lib/std/hash/md5.c3 index b0c3af751..50d57b39b 100644 --- a/lib/std/hash/md5.c3 +++ b/lib/std/hash/md5.c3 @@ -13,9 +13,9 @@ struct Md5 uint[16] block; } -def HmacMd5 = Hmac(); -def hmac = hmac::hash(); -def pbkdf2 = hmac::pbkdf2(); +def HmacMd5 = Hmac<[Md5, HASH_BYTES, BLOCK_BYTES]>; +def hmac = hmac::hash<[Md5, HASH_BYTES, BLOCK_BYTES]>; +def pbkdf2 = hmac::pbkdf2<[Md5, HASH_BYTES, BLOCK_BYTES]>; fn char[HASH_BYTES] hash(char[] data) { diff --git a/lib/std/hash/sha1.c3 b/lib/std/hash/sha1.c3 index 391061b80..90486e06b 100644 --- a/lib/std/hash/sha1.c3 +++ b/lib/std/hash/sha1.c3 @@ -18,9 +18,9 @@ struct Sha1 char[BLOCK_BYTES] buffer; } -def HmacSha1 = Hmac(); -def hmac = hmac::hash(); -def pbkdf2 = hmac::pbkdf2(); +def HmacSha1 = Hmac<[Sha1, HASH_BYTES, BLOCK_BYTES]>; +def hmac = hmac::hash<[Sha1, HASH_BYTES, BLOCK_BYTES]>; +def pbkdf2 = hmac::pbkdf2<[Sha1, HASH_BYTES, BLOCK_BYTES]>; fn char[HASH_BYTES] hash(char[] data) { diff --git a/lib/std/hash/sha256.c3 b/lib/std/hash/sha256.c3 index b18200c96..acd08c3de 100644 --- a/lib/std/hash/sha256.c3 +++ b/lib/std/hash/sha256.c3 @@ -34,9 +34,9 @@ struct Sha256 char[BLOCK_SIZE] buffer; } -def HmacSha256 = Hmac(); -def hmac = hmac::hash(); -def pbkdf2 = hmac::pbkdf2(); +def HmacSha256 = Hmac<[Sha256, HASH_SIZE, BLOCK_SIZE]>; +def hmac = hmac::hash<[Sha256, HASH_SIZE, BLOCK_SIZE]>; +def pbkdf2 = hmac::pbkdf2<[Sha256, HASH_SIZE, BLOCK_SIZE]>; fn char[HASH_SIZE] hash(char[] data) { diff --git a/lib/std/io/path.c3 b/lib/std/io/path.c3 index fa49d294a..f646cbbe0 100644 --- a/lib/std/io/path.c3 +++ b/lib/std/io/path.c3 @@ -7,7 +7,7 @@ const char PREFERRED_SEPARATOR_WIN32 = '\\'; const char PREFERRED_SEPARATOR_POSIX = '/'; const char PREFERRED_SEPARATOR = env::WIN32 ? PREFERRED_SEPARATOR_WIN32 : PREFERRED_SEPARATOR_POSIX; -def PathList = List(); +def PathList = List<[Path]>; fault PathResult { diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index aa76cefe2..9410061a8 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -90,33 +90,33 @@ fault MatrixError MATRIX_INVERSE_DOESNT_EXIST, } -def Complexf = Complex(); -def Complex = Complex(); -def COMPLEX_IDENTITY = complex::IDENTITY(); -def COMPLEXF_IDENTITY = complex::IDENTITY(); +def Complexf = Complex<[float]>; +def Complex = Complex<[double]>; +def COMPLEX_IDENTITY = complex::IDENTITY<[double]>; +def COMPLEXF_IDENTITY = complex::IDENTITY<[float]>; -def Quaternionf = Quaternion(); -def Quaternion = Quaternion(); -def QUATERNION_IDENTITY = quaternion::IDENTITY(); -def QUATERNIONF_IDENTITY = quaternion::IDENTITY(); +def Quaternionf = Quaternion<[float]>; +def Quaternion = Quaternion<[double]>; +def QUATERNION_IDENTITY = quaternion::IDENTITY<[double]>; +def QUATERNIONF_IDENTITY = quaternion::IDENTITY<[float]>; -def Matrix2f = Matrix2x2(); -def Matrix2 = Matrix2x2(); -def Matrix3f = Matrix3x3(); -def Matrix3 = Matrix3x3(); -def Matrix4f = Matrix4x4(); -def Matrix4 = Matrix4x4(); -def matrix4_ortho = matrix::ortho(); -def matrix4_perspective = matrix::perspective(); -def matrix4f_ortho = matrix::ortho(); -def matrix4f_perspective = matrix::perspective(); +def Matrix2f = Matrix2x2<[float]>; +def Matrix2 = Matrix2x2<[double]>; +def Matrix3f = Matrix3x3<[float]>; +def Matrix3 = Matrix3x3<[double]>; +def Matrix4f = Matrix4x4<[float]>; +def Matrix4 = Matrix4x4<[double]>; +def matrix4_ortho = matrix::ortho<[double]>; +def matrix4_perspective = matrix::perspective<[double]>; +def matrix4f_ortho = matrix::ortho<[float]>; +def matrix4f_perspective = matrix::perspective<[float]>; -def MATRIX2_IDENTITY = matrix::IDENTITY2(); -def MATRIX2F_IDENTITY = matrix::IDENTITY2(); -def MATRIX3_IDENTITY = matrix::IDENTITY3(); -def MATRIX3F_IDENTITY = matrix::IDENTITY3(); -def MATRIX4_IDENTITY = matrix::IDENTITY4(); -def MATRIX4F_IDENTITY = matrix::IDENTITY4(); +def MATRIX2_IDENTITY = matrix::IDENTITY2<[double]>; +def MATRIX2F_IDENTITY = matrix::IDENTITY2<[float]>; +def MATRIX3_IDENTITY = matrix::IDENTITY3<[double]>; +def MATRIX3F_IDENTITY = matrix::IDENTITY3<[float]>; +def MATRIX4_IDENTITY = matrix::IDENTITY4<[double]>; +def MATRIX4F_IDENTITY = matrix::IDENTITY4<[float]>; <* diff --git a/lib/std/math/math_vector.c3 b/lib/std/math/math_vector.c3 index f2613c5ac..9cdf44f3e 100644 --- a/lib/std/math/math_vector.c3 +++ b/lib/std/math/math_vector.c3 @@ -66,8 +66,8 @@ fn Vec3 Vec3.refract(self, Vec3 n, double r) => refract3(self, n, r); fn void ortho_normalize(Vec3f* v1, Vec3f* v2) => ortho_normalize3(v1, v2); fn void ortho_normalized(Vec3* v1, Vec3* v2) => ortho_normalize3(v1, v2); -fn Matrix4f matrix4f_look_at(Vec3f eye, Vec3f target, Vec3f up) @deprecated => matrix::look_at()(eye, target, up); -fn Matrix4 matrix4_look_at(Vec3 eye, Vec3 target, Vec3 up) @deprecated => matrix::look_at()(eye, target, up); +fn Matrix4f matrix4f_look_at(Vec3f eye, Vec3f target, Vec3f up) @deprecated => matrix::look_at<[float]>(eye, target, up); +fn Matrix4 matrix4_look_at(Vec3 eye, Vec3 target, Vec3 up) @deprecated => matrix::look_at<[double]>(eye, target, up); fn Vec3f Vec3f.rotate_quat(self, Quaternionf q) => rotate_by_quat3(self, q); fn Vec3 Vec3.rotate_quat(self, Quaternion q) => rotate_by_quat3(self, q); diff --git a/lib/std/net/url.c3 b/lib/std/net/url.c3 index 3514c100e..e5ce59c34 100644 --- a/lib/std/net/url.c3 +++ b/lib/std/net/url.c3 @@ -243,11 +243,11 @@ fn String Url.to_string(&self, Allocator allocator = allocator::heap()) @dynamic }; } -def UrlQueryValueList = List(); +def UrlQueryValueList = List<[String]>; struct UrlQueryValues { - inline HashMap() map; + inline HashMap<[String, UrlQueryValueList]> map; UrlQueryValueList key_order; } diff --git a/lib/std/os/backtrace.c3 b/lib/std/os/backtrace.c3 index f7c6f0bf1..79e118ccf 100644 --- a/lib/std/os/backtrace.c3 +++ b/lib/std/os/backtrace.c3 @@ -91,7 +91,7 @@ fn void*[] capture_current(void*[] buffer) $endswitch } -def BacktraceList = List(); +def BacktraceList = List<[Backtrace]>; def symbolize_backtrace = linux::symbolize_backtrace @if(env::LINUX); def symbolize_backtrace = win32::symbolize_backtrace @if(env::WIN32); diff --git a/lib/std/sort/countingsort.c3 b/lib/std/sort/countingsort.c3 index fa28f2cb9..3101cc1e3 100644 --- a/lib/std/sort/countingsort.c3 +++ b/lib/std/sort/countingsort.c3 @@ -11,17 +11,17 @@ Sort list using the counting sort algorithm. macro countingsort(list, key_fn = EMPTY_MACRO_SLOT) @builtin { usz len = sort::len_from_list(list); - cs::csort(<$typeof(list), $typeof(key_fn)>)(list, 0, len, key_fn, ~((uint)0)); + cs::csort<[$typeof(list), $typeof(key_fn)]>(list, 0, len, key_fn, ~((uint)0)); } macro insertionsort_indexed(list, start, end, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin { - is::isort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, (usz)start, (usz)end, cmp, context); + is::isort<[$typeof(list), $typeof(cmp), $typeof(context)]>(list, (usz)start, (usz)end, cmp, context); } macro quicksort_indexed(list, start, end, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin { - qs::qsort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, (isz)start, (isz)(end-1), cmp, context); + qs::qsort<[$typeof(list), $typeof(cmp), $typeof(context)]>(list, (isz)start, (isz)(end-1), cmp, context); } module std::sort::cs(); diff --git a/lib/std/sort/insertionsort.c3 b/lib/std/sort/insertionsort.c3 index ab1c6b371..041458dca 100644 --- a/lib/std/sort/insertionsort.c3 +++ b/lib/std/sort/insertionsort.c3 @@ -10,10 +10,10 @@ macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @b { $if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR): $typeof((*list)[0])[] list2 = list; - is::isort(<$typeof(list2), $typeof(cmp), $typeof(context)>)(list2, 0, list.len, cmp, context); + is::isort<[$typeof(list2), $typeof(cmp), $typeof(context)]>(list2, 0, list.len, cmp, context); $else usz len = sort::len_from_list(list); - is::isort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len, cmp, context); + is::isort<[$typeof(list), $typeof(cmp), $typeof(context)]>(list, 0, (isz)len, cmp, context); $endif } diff --git a/lib/std/sort/quicksort.c3 b/lib/std/sort/quicksort.c3 index 156d6a2f6..24701ea53 100644 --- a/lib/std/sort/quicksort.c3 +++ b/lib/std/sort/quicksort.c3 @@ -11,10 +11,10 @@ macro quicksort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @built { $if @typekind(list) == POINTER &&& (@typekind(*list) == ARRAY || @typekind(*list) == VECTOR): $typeof((*list)[0])[] list2 = list; - qs::qsort(<$typeof(list2), $typeof(cmp), $typeof(context)>)(list2, 0, (isz)list.len - 1, cmp, context); + qs::qsort<[$typeof(list2), $typeof(cmp), $typeof(context)]>(list2, 0, (isz)list.len - 1, cmp, context); $else usz len = sort::len_from_list(list); - qs::qsort(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len - 1, cmp, context); + qs::qsort<[$typeof(list), $typeof(cmp), $typeof(context)]>(list, 0, (isz)len - 1, cmp, context); $endif } @@ -30,7 +30,7 @@ list will be partially sorted. macro quickselect(list, isz k, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @builtin { usz len = sort::len_from_list(list); - return qs::qselect(<$typeof(list), $typeof(cmp), $typeof(context)>)(list, 0, (isz)len - 1, k, cmp, context); + return qs::qselect<[$typeof(list), $typeof(cmp), $typeof(context)]>(list, 0, (isz)len - 1, k, cmp, context); } module std::sort::qs(); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 81028a106..d7deb13b5 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -615,7 +615,11 @@ TypeInfo *parse_type_with_base(ParseContext *c, TypeInfo *type_info) type_info = parse_array_type_index(c, type_info); break; case TOKEN_LESS: - if (c->lexer.token_type != TOKEN_LBRACKET) break; + if (c->lexer.token_type != TOKEN_LBRACKET) + { + PRINT_ERROR_HERE("This looks like you're comparing a type? Or did you intend to write a generic type? In that case the syntax is 'Foo<[int]>'."); + return poisoned_type_info; + } type_info = parse_generic_type(c, type_info, true); break; case TOKEN_LGENPAR: diff --git a/test/test_suite/generic/generic_parsing.c3 b/test/test_suite/generic/generic_parsing.c3 new file mode 100644 index 000000000..b4c2425a6 --- /dev/null +++ b/test/test_suite/generic/generic_parsing.c3 @@ -0,0 +1,22 @@ +module test; +import std; +def ListStr = List(); +fn void test() +{ + List a = List<...>.new_init(); // #error: This looks like you're comparing a +} + +fn void test2() +{ + List<[String]> a = List<...>.new_init(); // #error: This looks like you're comparing a +} + +fn void test3() +{ + List() a = List<[...]>.new_init(); // #error: An expression was expected +} + +fn void main() +{ + List a = List.new_init(); // #error: This looks like you're comparing a +} \ No newline at end of file