Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stdlib] Add optional small buffer optimization to List, take 2 #2825

Open
wants to merge 103 commits into
base: nightly
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
e83c663
Add sbo to List
gabrieldemarmiesse May 25, 2024
c9b1d74
Merge branch 'nightly' into sbo_take_2
gabrieldemarmiesse May 26, 2024
d3db455
Dummy modification
gabrieldemarmiesse May 26, 2024
935133c
Revert the dummy modification
gabrieldemarmiesse May 26, 2024
a759dfc
Add the missing Parameter section to the Span constructor
gabrieldemarmiesse May 26, 2024
ad2a5d8
Squash all
gabrieldemarmiesse Jun 22, 2024
9000440
[stdlib] Add a `unsafe_assume_initialized` constructor to `InlineArray`
gabrieldemarmiesse Jun 25, 2024
94aa4c3
Reword docstring
gabrieldemarmiesse Jun 25, 2024
419eae2
Merge branch 'nightly' into add_new_methods
gabrieldemarmiesse Jun 25, 2024
65f3701
Fix incorrect docstring and test
gabrieldemarmiesse Jun 25, 2024
4ec64d9
Remove func call
gabrieldemarmiesse Jun 25, 2024
2103632
[stdlib] Add static method `InlineArray.unsafe_uninitialized()`
gabrieldemarmiesse Jun 25, 2024
a1bb080
Merge branch 'nightly' into add_unsafe_uninitialized_array_constructor
gabrieldemarmiesse Jun 26, 2024
bba4183
Merge branch 'nightly' into add_new_methods
gabrieldemarmiesse Jun 26, 2024
f92d948
Merge branch 'nightly' into sbo_take_2
gabrieldemarmiesse Jun 27, 2024
9af201a
Merge branch 'nightly' into fix_destructor_inlinearray
gabrieldemarmiesse Jun 27, 2024
ad0bc0e
[stdlib] Add trait `CollectionElementNew` to a few structs
gabrieldemarmiesse Jun 28, 2024
fe96ef8
[stdlib] Add `CollectionElementNew` trait to `Dict` and `DictEntry`
gabrieldemarmiesse Jun 28, 2024
a1a4785
[stdlib] Add the trait `CollectionElementNew` to `List`
gabrieldemarmiesse Jun 28, 2024
3b98599
[stdlib] Add `CollectionElementNew` to new traits
gabrieldemarmiesse Jun 28, 2024
0d2341c
Add unit test for legacy pointer
gabrieldemarmiesse Jun 28, 2024
c7a6801
Add test for arc
gabrieldemarmiesse Jun 28, 2024
1a1813a
Add the test for pointer copy
gabrieldemarmiesse Jun 28, 2024
87872f0
[stdlib] Add `CollectionElementNew` to a few structs, part 3
gabrieldemarmiesse Jun 28, 2024
af298fd
add the traits explicitly
gabrieldemarmiesse Jun 28, 2024
95e5b79
[stdlib] Add CollectionElementNew to a few structs, part 4
gabrieldemarmiesse Jun 28, 2024
4bcd776
Merge branch 'moar_copy_constructors' into make_dict_list_set_work_wi…
gabrieldemarmiesse Jun 30, 2024
54ec253
Merge branch 'moar_collectionelementnew' into make_dict_list_set_work…
gabrieldemarmiesse Jun 30, 2024
06d075e
Merge branch 'more_explicit_copy_traits' into make_dict_list_set_work…
gabrieldemarmiesse Jun 30, 2024
a517dd4
Merge branch 'add_copy_constructors' into make_dict_list_set_work_wit…
gabrieldemarmiesse Jun 30, 2024
22ead11
Merge branch 'more_copy_constructors' into make_dict_list_set_work_wi…
gabrieldemarmiesse Jun 30, 2024
4991574
Merge branch 'give_collectionelementnew_trait_to_list' into make_dict…
gabrieldemarmiesse Jun 30, 2024
f8457a3
I only need to fix sort next
gabrieldemarmiesse Jun 30, 2024
336b7e7
Fix most of the sort errors
gabrieldemarmiesse Jun 30, 2024
adc370b
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 1, 2024
a81fe92
Removed diff
gabrieldemarmiesse Jul 1, 2024
e326324
[stdlib] All done with a few bugs
gabrieldemarmiesse Jul 11, 2024
3c16445
Merge branch 'explicit_copy_take_2' into make_dict_list_set_work_with…
gabrieldemarmiesse Jul 11, 2024
1f5edef
Reduce diff in types.mojo
gabrieldemarmiesse Jul 11, 2024
8c65ce1
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 11, 2024
c80e260
Merge branch 'nightly' into add_new_methods
gabrieldemarmiesse Jul 15, 2024
1f37b1c
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 15, 2024
a89778e
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 17, 2024
f18f72a
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 21, 2024
30c3d62
Fix recursive reference to self issue
gabrieldemarmiesse Jul 21, 2024
57c22d6
Revert the contrustor move
gabrieldemarmiesse Jul 21, 2024
95a1f36
Better comments
gabrieldemarmiesse Jul 21, 2024
954981c
Rewording
gabrieldemarmiesse Jul 21, 2024
65fd9fe
Merge branch 'nightly' into remove_copyable_from_collectionelement
gabrieldemarmiesse Jul 22, 2024
cc38b93
[stdlib] Remove `Copyable` From `CollectionElement`
gabrieldemarmiesse Jul 22, 2024
44b7910
[stdlib] Remove `CollectionElementNew` and use only `CollectionElement`
gabrieldemarmiesse Jul 22, 2024
d1bf7c5
Merge branch 'nightly' into fix_destructor_inlinearray
gabrieldemarmiesse Jul 23, 2024
e319e58
Revert change to inline array, use ptrs now
gabrieldemarmiesse Jul 23, 2024
b682743
Reverted most changes
gabrieldemarmiesse Jul 23, 2024
8e13f6b
Merge branch 'nightly' into add_new_methods
gabrieldemarmiesse Jul 23, 2024
c7ebc80
Merge branch 'fix_destructor_inlinearray' into add_new_methods
gabrieldemarmiesse Jul 23, 2024
53c2f51
Fix function
gabrieldemarmiesse Jul 23, 2024
de3407d
Merge branch 'nightly' into add_unsafe_uninitialized_array_constructor
gabrieldemarmiesse Jul 23, 2024
fe8584d
Merge branch 'add_new_methods' into add_unsafe_uninitialized_array_co…
gabrieldemarmiesse Jul 23, 2024
d0b92b8
Simplify the API
gabrieldemarmiesse Jul 23, 2024
e139d6b
Simplify the api
gabrieldemarmiesse Jul 23, 2024
023f877
Simplify some stuff
gabrieldemarmiesse Jul 23, 2024
6e35670
Simplify again
gabrieldemarmiesse Jul 23, 2024
aa5a005
Simplify more
gabrieldemarmiesse Jul 23, 2024
f2bf4a4
Add docstring
gabrieldemarmiesse Jul 23, 2024
755176b
Remove this_size and make parameters infer-only
gabrieldemarmiesse Jul 23, 2024
d4f3b62
Merge branch 'remove_collectionelementnew' into common_branch
gabrieldemarmiesse Jul 23, 2024
ec2a548
Merge branch 'add_unsafe_uninitialized_array_constructor' into common…
gabrieldemarmiesse Jul 23, 2024
5f11c71
Fix all incompatible changes
gabrieldemarmiesse Jul 23, 2024
151c3df
Merge branch 'common_branch' into sbo_take_2
gabrieldemarmiesse Jul 23, 2024
3f88841
Merge branch 'nightly' into sbo_take_2
gabrieldemarmiesse Jul 24, 2024
b031e06
Fixed `List.__moveinit__`
gabrieldemarmiesse Jul 24, 2024
bed39ae
Re-enabled dtor test
gabrieldemarmiesse Jul 24, 2024
4891d5f
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Jul 27, 2024
5876d64
Merge branch 'make_dict_list_set_work_with_collectionelementnew' into…
gabrieldemarmiesse Jul 27, 2024
6c0fea7
Merge branch 'remove_copyable_from_collectionelement' into remove_col…
gabrieldemarmiesse Jul 27, 2024
704390a
Merge branch 'nightly' into fix_destructor_inlinearray
gabrieldemarmiesse Jul 27, 2024
598e4ea
Fix import
gabrieldemarmiesse Jul 27, 2024
92c533b
Merge branch 'fix_destructor_inlinearray' into add_new_methods
gabrieldemarmiesse Jul 27, 2024
f9fa2cb
Merge branch 'add_new_methods' into add_unsafe_uninitialized_array_co…
gabrieldemarmiesse Jul 27, 2024
a52c1a7
Merge branch 'add_unsafe_uninitialized_array_constructor' into common…
gabrieldemarmiesse Jul 27, 2024
e4dd0de
Merge branch 'remove_collectionelementnew' into common_branch
gabrieldemarmiesse Jul 27, 2024
c13eb8f
Merge branch 'common_branch' into sbo_take_2
gabrieldemarmiesse Jul 28, 2024
66699ea
Removed unrelated files
gabrieldemarmiesse Jul 28, 2024
172f5c0
Merge branch 'nightly' into make_dict_list_set_work_with_collectionel…
gabrieldemarmiesse Aug 1, 2024
f4084a5
Merge branch 'make_dict_list_set_work_with_collectionelementnew' into…
gabrieldemarmiesse Aug 1, 2024
24de66c
Merge branch 'remove_copyable_from_collectionelement' into remove_col…
gabrieldemarmiesse Aug 1, 2024
ae0245d
Merge branch 'remove_collectionelementnew' into common_branch
gabrieldemarmiesse Aug 1, 2024
1a0ac75
Merge branch 'common_branch' into sbo_take_2
gabrieldemarmiesse Aug 1, 2024
5883db2
[stdlib] Use memcpy in list when moving trivial types
gabrieldemarmiesse Aug 1, 2024
05b9311
III
gabrieldemarmiesse Aug 1, 2024
aa52df9
Merge branch 'nightly' into use_memcpy_for_trivial_types
gabrieldemarmiesse Aug 2, 2024
221db24
Use export instead of a one-off definition
gabrieldemarmiesse Aug 2, 2024
cb75011
Merge branch 'use_memcpy_for_trivial_types' into common_branch
gabrieldemarmiesse Aug 2, 2024
bfcc65c
Merge branch 'common_branch' into sbo_take_2
gabrieldemarmiesse Aug 2, 2024
bc74730
Use memcpy even with sbo
gabrieldemarmiesse Aug 2, 2024
43b92da
Added test
gabrieldemarmiesse Aug 2, 2024
63eced7
Use steal_data()
gabrieldemarmiesse Aug 2, 2024
23a90c2
Merge branch 'use_memcpy_for_trivial_types' into common_branch
gabrieldemarmiesse Aug 2, 2024
c90bde4
Merge branch 'common_branch' into sbo_take_2
gabrieldemarmiesse Aug 2, 2024
52ced05
Merge branch 'nightly' into sbo_take_2
gabrieldemarmiesse Sep 14, 2024
934a1f2
Remove changes in object.mojo
gabrieldemarmiesse Sep 14, 2024
08c80dd
Fix compilation issue in tests
gabrieldemarmiesse Sep 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions stdlib/src/builtin/reversed.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,20 @@ fn reversed[T: ReversibleRange](value: T) -> _StridedRange:


fn reversed[
T: CollectionElement
T: CollectionElement,
small_buffer_size: Int,
](
value: Reference[List[T], _, _],
value: Reference[List[T, small_buffer_size], _, _],
) -> _ListIter[
T, value.is_mutable, value.lifetime, False
T, small_buffer_size, value.is_mutable, value.lifetime, False
]:
"""Get a reversed iterator of the input list.

**Note**: iterators are currently non-raising.

Parameters:
T: The type of the elements in the list.
small_buffer_size: The size of the small buffer in the list.

Args:
value: The list to get the reversed iterator of.
Expand Down
159 changes: 132 additions & 27 deletions stdlib/src/collections/list.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ from utils import Span
@value
struct _ListIter[
T: CollectionElement,
small_buffer_size: Int,
list_mutability: Bool,
list_lifetime: AnyLifetime[list_mutability].type,
forward: Bool = True,
Expand All @@ -42,12 +43,13 @@ struct _ListIter[

Parameters:
T: The type of the elements in the list.
small_buffer_size: The size of the small buffer.
list_mutability: Whether the reference to the list is mutable.
list_lifetime: The lifetime of the List
forward: The iteration direction. `False` is backwards.
"""

alias list_type = List[T]
alias list_type = List[T, small_buffer_size]

var index: Int
var src: Reference[Self.list_type, list_mutability, list_lifetime]
Expand All @@ -74,17 +76,23 @@ struct _ListIter[
return self.index


struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
struct List[T: CollectionElement, small_buffer_size: Int = 0](
CollectionElement, Sized, Boolable
):
"""The `List` type is a dynamically-allocated list.

It supports pushing and popping from the back resizing the underlying
storage as needed. When it is deallocated, it frees its memory.

Parameters:
T: The type of the elements.
small_buffer_size: Set if you need small buffer optimization.
"""

# Fields
alias _small_buffer_type = InlineArray[T, small_buffer_size]
alias sbo_enabled = Self.small_buffer_size != 0
var _small_buffer: Self._small_buffer_type
var data: UnsafePointer[T]
"""The underlying storage for the list."""
var size: Int
Expand All @@ -99,10 +107,23 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
fn __init__(inout self):
"""Constructs an empty list."""
self.data = UnsafePointer[T]()
self._small_buffer = Self._small_buffer_type(unsafe_uninitialized=True)

@parameter
if Self.sbo_enabled:
self.data = self._small_buffer.unsafe_ptr()
self.capacity = Self.small_buffer_size
else:
# `self.data = UnsafePointer[T]()` is not there because
# we need to call it before calling
# `self.data = self._small_buffer.unsafe_ptr()`.
# Otherwise, we get the following compiler error:
# "potential indirect access to uninitialized value 'self.data'"
self.capacity = 0

self.size = 0
self.capacity = 0

fn __init__(inout self, existing: Self):
fn __init__(inout self, existing: List[T, _]):
"""Creates a deep copy of the given list.

Args:
Expand All @@ -118,8 +139,19 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
Args:
capacity: The requested capacity of the list.
"""
self.data = UnsafePointer[T].alloc(capacity)
self.size = 0
self._small_buffer = Self._small_buffer_type(unsafe_uninitialized=True)

@parameter
if Self.sbo_enabled:
if capacity <= Self.small_buffer_size:
self.capacity = Self.small_buffer_size
# needed to avoid "potential indirect access to uninitialized value 'self.data'"
self.data = UnsafePointer[T]()
self.data = self._small_buffer.unsafe_ptr()
return

self.data = UnsafePointer[T].alloc(capacity)
self.capacity = capacity

# TODO: Avoid copying elements in once owned varargs
Expand Down Expand Up @@ -161,16 +193,33 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
self.data = unsafe_pointer
self.size = size
self.capacity = capacity
self._small_buffer = Self._small_buffer_type(unsafe_uninitialized=True)

@always_inline
fn _sbo_is_in_use(self) -> Bool:
@parameter
if not Self.sbo_enabled:
return False
return self.data == self._small_buffer.unsafe_ptr()

fn __moveinit__(inout self, owned existing: Self):
"""Move data of an existing list into a new one.

Args:
existing: The existing list.
"""
self.data = existing.data
self.size = existing.size
self.capacity = existing.capacity
self._small_buffer = existing._small_buffer

@parameter
if Self.sbo_enabled:
if existing._sbo_is_in_use():
# Needed to avoid "potential indirect access to uninitialized value 'self.data'"
self.data = UnsafePointer[T]()
self.data = self._small_buffer.unsafe_ptr()
return
self.data = existing.data

fn __copyinit__(inout self, existing: Self):
"""Creates a deepcopy of the given list.
Expand All @@ -187,7 +236,12 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
"""Destroy all elements in the list and free its memory."""
for i in range(self.size):
destroy_pointee(self.data + i)
if self.data:
self._free_data_if_possible()

@always_inline
fn _free_data_if_possible(inout self):
"""Free the memory of the list."""
if self.data and not self._sbo_is_in_use():
self.data.free()

# ===-------------------------------------------------------------------===#
Expand Down Expand Up @@ -216,7 +270,9 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
@always_inline
fn __contains__[
T2: ComparableCollectionElement
](self: List[T2], value: T) -> Bool:
](
self: Reference[List[T2, Self.small_buffer_size], _, _], value: T
) -> Bool:
"""Verify if a given value is present in the list.

```mojo
Expand All @@ -235,7 +291,7 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
"""

constrained[_type_is_eq[T, T2](), "value type is not self.T"]()
for i in self:
for i in self[]:
if i[] == rebind[T2](value):
return True
return False
Expand Down Expand Up @@ -291,7 +347,7 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):

fn __iter__(
self: Reference[Self, _, _],
) -> _ListIter[T, self.is_mutable, self.lifetime]:
) -> _ListIter[T, Self.small_buffer_size, self.is_mutable, self.lifetime]:
"""Iterate over elements of the list, returning immutable references.

Returns:
Expand All @@ -301,7 +357,9 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):

fn __reversed__(
self: Reference[Self, _, _]
) -> _ListIter[T, self.is_mutable, self.lifetime, False]:
) -> _ListIter[
T, Self.small_buffer_size, self.is_mutable, self.lifetime, False
]:
"""Iterate backwards over the list, returning immutable references.

Returns:
Expand Down Expand Up @@ -329,7 +387,9 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
"""
return len(self) > 0

fn __str__[U: RepresentableCollectionElement](self: List[U]) -> String:
fn __str__[
U: RepresentableCollectionElement
](self: Reference[List[U, Self.small_buffer_size], _, _]) -> String:
"""Returns a string representation of a `List`.

Note that since we can't condition methods on a trait yet,
Expand All @@ -356,28 +416,30 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
# in the final string, we assume that str(x) will be at least one char.
var minimum_capacity = (
2 # '[' and ']'
+ len(self) * 3 # str(x) and ", "
+ len(self[]) * 3 # str(x) and ", "
- 2 # remove the last ", "
)
var string_buffer = List[UInt8](capacity=minimum_capacity)
string_buffer.append(0) # Null terminator
var result = String(string_buffer^)
result += "["
for i in range(len(self)):
result += repr(self[i])
if i < len(self) - 1:
for i in range(len(self[])):
result += repr(self[][i])
if i < len(self[]) - 1:
result += ", "
result += "]"
return result

fn __repr__[U: RepresentableCollectionElement](self: List[U]) -> String:
fn __repr__[
U: RepresentableCollectionElement
](self: Reference[List[U, Self.small_buffer_size], _, _]) -> String:
"""Returns a string representation of a `List`.
Note that since we can't condition methods on a trait yet,
the way to call this method is a bit special. Here is an example below:

```mojo
var my_list = List[Int](1, 2, 3)
print(my_list.__repr__(my_list))
print(my_list.__repr__())
```

When the compiler supports conditional methods, then a simple `repr(my_list)` will
Expand All @@ -392,21 +454,50 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
Returns:
A string representation of the list.
"""
return self.__str__()
return self[].__str__()

# ===-------------------------------------------------------------------===#
# Methods
# ===-------------------------------------------------------------------===#

@always_inline
fn _realloc(inout self, new_capacity: Int):
@parameter
if Self.sbo_enabled:
self._realloc_with_sbo(new_capacity)
else:
self._realloc_without_sbo(new_capacity)

@always_inline
fn _realloc_with_sbo(inout self, new_capacity: Int):
var new_data: UnsafePointer[T]

if new_capacity <= Self.small_buffer_size:
# We don't need to move anything if the data is already stored in the
# inline buffer and the new capacity still fits in that inline buffer.
if self._sbo_is_in_use():
return
new_data = self._small_buffer.unsafe_ptr()
self.capacity = Self.small_buffer_size
else:
new_data = UnsafePointer[T].alloc(new_capacity)
self.capacity = new_capacity

for i in range(self.size):
move_pointee(src=self.data + i, dst=new_data + i)

self._free_data_if_possible()
self.data = new_data

@always_inline
fn _realloc_without_sbo(inout self, new_capacity: Int):
var new_data = UnsafePointer[T].alloc(new_capacity)

for i in range(self.size):
move_pointee(src=self.data + i, dst=new_data + i)

if self.data:
self.data.free()
self._free_data_if_possible()

self.data = new_data
self.capacity = new_capacity

Expand Down Expand Up @@ -467,13 +558,13 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
if x == 0:
self.clear()
return
var orig = List(self)
var orig = List[small_buffer_size = Self.small_buffer_size](self)
self.reserve(len(self) * x)
for i in range(x - 1):
self.extend(orig)

@always_inline
fn extend(inout self, owned other: List[T]):
fn extend(inout self, owned other: List[T, _]):
"""Extends this list by consuming the elements of `other`.

Args:
Expand Down Expand Up @@ -636,7 +727,7 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
fn index[
C: ComparableCollectionElement
](
self: Reference[List[C]],
self: Reference[List[C, Self.small_buffer_size], _, _],
value: C,
start: Int = 0,
stop: Optional[Int] = None,
Expand Down Expand Up @@ -701,6 +792,18 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
Returns:
The underlying data.
"""

@parameter
if Self.sbo_enabled:
if self._sbo_is_in_use():
# We use here the fact that if we reallocate for something
# that doesn't fit in the small buffer, then a heap allocation
# must be done. We allocate more than we need and it's not great
# for performance.
# TODO: add an argument "force_alloc" to the _realloc method
# to force heap allocation even if the capacity is smaller than the
# small buffer size.
self._realloc(Self.small_buffer_size + 1)
var ptr = self.data
self.data = UnsafePointer[T]()
self.size = 0
Expand Down Expand Up @@ -826,7 +929,9 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
)
return (self[].data + idx_as_int)[]

fn count[T: ComparableCollectionElement](self: List[T], value: T) -> Int:
fn count[
U: ComparableCollectionElement
](self: Reference[List[U, Self.small_buffer_size], _, _], value: U) -> Int:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to use references in those situations otherwise the compiler wasn't happy at all with the extra parameter. The behavior didn't change. Same for other methods like __str__

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you file compiler bugs please? Your PRs are definitely hitting a few and I want to make sure they're all captured! Perhaps a comment in the code too referencing such bugs?

Copy link
Contributor Author

@gabrieldemarmiesse gabrieldemarmiesse May 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind filing those bugs but can it be after the PR is merged? Making a minimal reproducible example can sometimes take a few minutes but it can also sometimes take a lot of time. I can make another PRs to add the TODOs later if that's okay with you.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, totally fine.

"""Counts the number of occurrences of a value in the list.
Note that since we can't condition methods on a trait yet,
the way to call this method is a bit special. Here is an example below.
Expand All @@ -840,7 +945,7 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
be enough.

Parameters:
T: The type of the elements in the list. Must implement the
U: The type of the elements in the list. Must implement the
traits `EqualityComparable` and `CollectionElement`.

Args:
Expand All @@ -850,7 +955,7 @@ struct List[T: CollectionElement](CollectionElement, Sized, Boolable):
The number of occurrences of the value in the list.
"""
var count = 0
for elem in self:
for elem in self[]:
if elem[] == value:
count += 1
return count
Expand Down
7 changes: 6 additions & 1 deletion stdlib/src/utils/span.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ struct Span[
self._len = len

@always_inline
fn __init__(inout self, list: Reference[List[T], is_mutable, lifetime]):
fn __init__[
small_buffer_size: Int
gabrieldemarmiesse marked this conversation as resolved.
Show resolved Hide resolved
](
inout self,
list: Reference[List[T, small_buffer_size], is_mutable, lifetime],
):
"""Construct a Span from a List.

Args:
Expand Down
Loading
Loading