diff --git a/lib/std/collections/linkedlist.c3 b/lib/std/collections/linkedlist.c3 index e6d5e20f3..8f7a411e2 100644 --- a/lib/std/collections/linkedlist.c3 +++ b/lib/std/collections/linkedlist.c3 @@ -245,6 +245,11 @@ fn Type! LinkedList.pop(&self) return self._last.value; } +fn bool LinkedList.is_empty(&self) +{ + return !self._first; +} + fn Type! LinkedList.pop_front(&self) { if (!self._first) return IteratorResult.NO_MORE_ELEMENT?; diff --git a/lib/std/collections/priorityqueue.c3 b/lib/std/collections/priorityqueue.c3 index 4f99b18ae..e83a00cb9 100644 --- a/lib/std/collections/priorityqueue.c3 +++ b/lib/std/collections/priorityqueue.c3 @@ -46,6 +46,7 @@ fn void PrivatePriorityQueue.temp_init(&self, usz initial_capacity = 16) @inline self.heap.new_init(initial_capacity, allocator::temp()) @inline; } + fn void PrivatePriorityQueue.push(&self, Type element) { self.heap.push(element); @@ -66,6 +67,15 @@ fn void PrivatePriorityQueue.push(&self, Type element) } } +fn void PrivatePriorityQueue.remove_at(&self, usz index) +{ + if (index == 0) + { + self.pop()!!; + return; + } + self.heap.remove_at(index); +} <* @require self != null *> diff --git a/lib/std/time/time.c3 b/lib/std/time/time.c3 index 17456432c..3d9f1cfb6 100644 --- a/lib/std/time/time.c3 +++ b/lib/std/time/time.c3 @@ -6,6 +6,8 @@ distinct Duration = long; distinct Clock = ulong; distinct NanoDuration (Printable) = long; +const Time FAR_FUTURE = long.max; +const Time FAR_PAST = long.min; const Duration US = 1; const Duration MS = 1_000; const Duration SEC = 1_000_000; @@ -15,6 +17,7 @@ const Duration DAY = 24 * HOUR; const Duration WEEK = 7 * DAY; const Duration MONTH = 30 * DAY; const Duration YEAR = 36525 * DAY / 100; +const Duration FOREVER = long.max; fn Duration us(long l) @inline => (Duration)l * US; fn Duration ms(long l) @inline => (Duration)l * MS; @@ -86,6 +89,13 @@ fn Time Time.add_hours(time, long hours) => time + (Time)(hours * (long)HOUR); fn Time Time.add_days(time, long days) => time + (Time)(days * (long)DAY); fn Time Time.add_weeks(time, long weeks) => time + (Time)(weeks * (long)WEEK); fn Time Time.add_duration(time, Duration duration) => time + (Time)duration; + +fn int Time.compare_to(time, Time other) +{ + if (time == other) return 0; + return time > other ? 1 : -1; +} + fn double Time.to_seconds(time) => (long)time / (double)SEC; fn Duration Time.diff_us(time, Time other) => (Duration)(time - other); fn double Time.diff_sec(time, Time other) => (long)time.diff_us(other) / (double)SEC; diff --git a/releasenotes.md b/releasenotes.md index f78475b9d..5ef5accd1 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -39,6 +39,7 @@ - Wrong error message for interface methods with body #1536. - Empty expression block would crash compiler with debug on #1554. - Improve infer conversions on constants, e.g. `ZString a = foo ? "a" : "b";` #1561 +- Show error when declarations do not start with `fn` in interfaces. #1565 ### Stdlib changes - Remove unintended print of `char[]` as String diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index a05004130..71c739bb7 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1770,6 +1770,10 @@ INLINE bool parse_interface_body(ParseContext *c, Decl *interface) { AstId contracts = 0; if (!parse_contracts(c, &contracts)) return poisoned_decl; + if (!tok_is(c, TOKEN_FN)) + { + RETURN_PRINT_ERROR_HERE("Interfaces can only have function declarations, and they must start with 'fn' as usual."); + } ASSIGN_DECL_OR_RET(Decl *interface_fn, parse_func_definition(c, contracts, FUNC_PARSE_INTERFACE), false); vec_add(fns, interface_fn); } diff --git a/test/test_suite/any/interface_no_fn.c3 b/test/test_suite/any/interface_no_fn.c3 new file mode 100644 index 000000000..62f323bc1 --- /dev/null +++ b/test/test_suite/any/interface_no_fn.c3 @@ -0,0 +1,4 @@ +interface IOp { + int val; // #error: Interfaces can only have function + int my_fn(); // missing fn +} \ No newline at end of file