Error with unsigned compare in @ensure when early returning 0 #1207. Added remove_first_item remove_last_item and remove_item as aliases for the match functions.

This commit is contained in:
Christoffer Lerno
2024-06-14 17:29:46 +02:00
parent 21fa006850
commit c94610f8a9
4 changed files with 61 additions and 6 deletions

View File

@@ -428,13 +428,12 @@ fn bool List.contains(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
return false; return false;
} }
/** /**
* @param [&inout] self "The list to remove elements from" * @param [&inout] self "The list to remove elements from"
* @param value "The value to remove" * @param value "The value to remove"
* @return "true if the value was found" * @return "true if the value was found"
**/ **/
fn bool List.remove_last_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE) fn bool List.remove_last_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
{ {
return @ok(self.remove_at(self.rindex_of(value))); return @ok(self.remove_at(self.rindex_of(value)));
} }
@@ -444,7 +443,7 @@ fn bool List.remove_last_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
* @param value "The value to remove" * @param value "The value to remove"
* @return "true if the value was found" * @return "true if the value was found"
**/ **/
fn bool List.remove_first_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE) fn bool List.remove_first_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
{ {
return @ok(self.remove_at(self.index_of(value))); return @ok(self.remove_at(self.index_of(value)));
} }
@@ -454,7 +453,7 @@ fn bool List.remove_first_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
* @param value "The value to remove" * @param value "The value to remove"
* @return "the number of deleted elements." * @return "the number of deleted elements."
**/ **/
fn usz List.remove_all_matches(&self, Type value) @if(ELEMENT_IS_EQUATABLE) fn usz List.remove_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
{ {
usz size = self.size; usz size = self.size;
for (usz i = size; i > 0; i--) for (usz i = size; i > 0; i--)
@@ -469,10 +468,12 @@ fn usz List.remove_all_matches(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
return size - self.size; return size - self.size;
} }
fn void List.remove_all_from(&self, List* other_list) @if(ELEMENT_IS_EQUATABLE) fn void List.remove_all_from(&self, List* other_list) @if(ELEMENT_IS_EQUATABLE)
{ {
if (!other_list.size) return; if (!other_list.size) return;
foreach (v : other_list) self.remove_all_matches(v); foreach (v : other_list) self.remove_item(v);
} }
/** /**
@@ -500,3 +501,36 @@ fn usz List.compact(&self) @if(ELEMENT_IS_POINTER)
} }
return size - self.size; return size - self.size;
} }
// --> Deprecated
/**
* @param [&inout] self "The list to remove elements from"
* @param value "The value to remove"
* @return "true if the value was found"
**/
fn bool List.remove_last_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE) @deprecated
{
return self.remove_last_item(value) @inline;
}
/**
* @param [&inout] self "The list to remove elements from"
* @param value "The value to remove"
* @return "true if the value was found"
**/
fn bool List.remove_first_match(&self, Type value) @if(ELEMENT_IS_EQUATABLE) @deprecated
{
return self.remove_first_item(value) @inline;
}
/**
* @param [&inout] self "The list to remove elements from"
* @param value "The value to remove"
* @return "the number of deleted elements."
**/
fn usz List.remove_all_matches(&self, Type value) @if(ELEMENT_IS_EQUATABLE) @deprecated
{
return self.remove_item(value) @inline;
}

View File

@@ -1,5 +1,16 @@
# C3C Release Notes # C3C Release Notes
## 0.6.1 Change list
### Changes / improvements
### Fixes
- Error with unsigned compare in `@ensure` when early returning 0 #1207.
### Stdlib changes
- Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions.
## 0.6.0 Change list ## 0.6.0 Change list
### Changes / improvements ### Changes / improvements

View File

@@ -5896,7 +5896,7 @@ static bool sema_expr_analyse_and_or(SemaContext *context, Expr *expr, Expr *lef
static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right, static bool sema_binary_is_unsigned_always_same_comparison(SemaContext *context, Expr *expr, Expr *left, Expr *right,
Type *lhs_type, Type *rhs_type) Type *lhs_type, Type *rhs_type)
{ {
if (context->active_scope.flags & SCOPE_MACRO) return true; if (context->active_scope.flags & (SCOPE_MACRO | SCOPE_ENSURE | SCOPE_ENSURE_MACRO)) return true;
if (!expr_is_const(left) && !expr_is_const(right)) return true; if (!expr_is_const(left) && !expr_is_const(right)) return true;
if (!type_is_integer(left->type)) return true; if (!type_is_integer(left->type)) return true;
if (expr_is_const(left) && type_is_unsigned(rhs_type)) if (expr_is_const(left) && type_is_unsigned(rhs_type))

View File

@@ -0,0 +1,10 @@
// Check that 0 <= buf is ok.
/**
* @ensure return <= buf.len
*/
fn usz foo(char[] buf) {
if (buf.len == 0) return 0;
// ... return some index into buf
return buf.len;
}