mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
fix roc_std to support seamless str slices
This commit is contained in:
parent
3978059aa2
commit
18e6dbd163
2 changed files with 17 additions and 10 deletions
|
@ -94,18 +94,18 @@ impl<T> RocList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.length
|
self.length & (isize::MAX as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_seamless_slice(&self) -> bool {
|
pub fn is_seamless_slice(&self) -> bool {
|
||||||
(self.capacity_or_ref_ptr as isize) < 0
|
((self.length | self.capacity_or_ref_ptr) as isize) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
if !self.is_seamless_slice() {
|
if !self.is_seamless_slice() {
|
||||||
self.capacity_or_ref_ptr
|
self.capacity_or_ref_ptr
|
||||||
} else {
|
} else {
|
||||||
self.length
|
self.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,8 +257,10 @@ where
|
||||||
|
|
||||||
// Copy the old elements to the new allocation.
|
// Copy the old elements to the new allocation.
|
||||||
unsafe {
|
unsafe {
|
||||||
copy_nonoverlapping(elements.as_ptr(), new_elements.as_ptr(), self.length);
|
copy_nonoverlapping(elements.as_ptr(), new_elements.as_ptr(), self.len());
|
||||||
}
|
}
|
||||||
|
// Clear the seamless slice bit since we now have clear ownership.
|
||||||
|
self.length = self.len();
|
||||||
|
|
||||||
new_elements
|
new_elements
|
||||||
}
|
}
|
||||||
|
@ -295,7 +297,7 @@ impl<T> RocList<T> {
|
||||||
///
|
///
|
||||||
/// May return a new RocList, if the provided one was not unique.
|
/// May return a new RocList, if the provided one was not unique.
|
||||||
pub fn reserve(&mut self, num_elems: usize) {
|
pub fn reserve(&mut self, num_elems: usize) {
|
||||||
let new_len = num_elems + self.length;
|
let new_len = num_elems + self.len();
|
||||||
let new_elems;
|
let new_elems;
|
||||||
let old_elements_ptr;
|
let old_elements_ptr;
|
||||||
|
|
||||||
|
@ -338,7 +340,7 @@ impl<T> RocList<T> {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Copy the old elements to the new allocation.
|
// Copy the old elements to the new allocation.
|
||||||
copy_nonoverlapping(old_elements_ptr, new_elems.as_ptr(), self.length);
|
copy_nonoverlapping(old_elements_ptr, new_elems.as_ptr(), self.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrease the current allocation's reference count.
|
// Decrease the current allocation's reference count.
|
||||||
|
@ -371,7 +373,7 @@ impl<T> RocList<T> {
|
||||||
|
|
||||||
self.update_to(Self {
|
self.update_to(Self {
|
||||||
elements: Some(new_elems),
|
elements: Some(new_elems),
|
||||||
length: self.length,
|
length: self.len(),
|
||||||
capacity_or_ref_ptr: new_len,
|
capacity_or_ref_ptr: new_len,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -392,7 +394,7 @@ impl<T> Deref for RocList<T> {
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
if let Some(elements) = self.elements {
|
if let Some(elements) = self.elements {
|
||||||
let elements = ptr::slice_from_raw_parts(elements.as_ptr().cast::<T>(), self.length);
|
let elements = ptr::slice_from_raw_parts(elements.as_ptr().cast::<T>(), self.len());
|
||||||
|
|
||||||
unsafe { &*elements }
|
unsafe { &*elements }
|
||||||
} else {
|
} else {
|
||||||
|
@ -424,7 +426,7 @@ where
|
||||||
{
|
{
|
||||||
fn partial_cmp(&self, other: &RocList<U>) -> Option<cmp::Ordering> {
|
fn partial_cmp(&self, other: &RocList<U>) -> Option<cmp::Ordering> {
|
||||||
// If one is longer than the other, use that as the ordering.
|
// If one is longer than the other, use that as the ordering.
|
||||||
match self.length.partial_cmp(&other.length) {
|
match self.len().partial_cmp(&other.len()) {
|
||||||
Some(Ordering::Equal) => {}
|
Some(Ordering::Equal) => {}
|
||||||
ord => return ord,
|
ord => return ord,
|
||||||
}
|
}
|
||||||
|
@ -448,7 +450,7 @@ where
|
||||||
{
|
{
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
// If one is longer than the other, use that as the ordering.
|
// If one is longer than the other, use that as the ordering.
|
||||||
match self.length.cmp(&other.length) {
|
match self.len().cmp(&other.len()) {
|
||||||
Ordering::Equal => {}
|
Ordering::Equal => {}
|
||||||
ord => return ord,
|
ord => return ord,
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,6 +698,11 @@ impl From<SendSafeRocStr> for RocStr {
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
union RocStrInner {
|
union RocStrInner {
|
||||||
|
// TODO: this really should be separated from the List type.
|
||||||
|
// Due to length specifying seamless slices for Str and capacity for Lists they should not share the same code.
|
||||||
|
// Currently, there are work arounds in RocList to handle both via removing the highest bit of length in many cases.
|
||||||
|
// With glue changes, we should probably rewrite these cleanly to match what is in the zig bitcode.
|
||||||
|
// It is definitely a bit stale now and I think the storage mechanism can be quite confusing with our extra pieces of state.
|
||||||
heap_allocated: ManuallyDrop<RocList<u8>>,
|
heap_allocated: ManuallyDrop<RocList<u8>>,
|
||||||
small_string: SmallString,
|
small_string: SmallString,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue