mirror of
				https://github.com/roc-lang/roc.git
				synced 2025-11-04 06:38:28 +00:00 
			
		
		
		
	Fixes #7065 in List.dropAt, author: @bhansconnect
This commit is contained in:
		
							parent
							
								
									14bfa91ff3
								
							
						
					
					
						commit
						c10b25cf6e
					
				
					 1 changed files with 18 additions and 17 deletions
				
			
		| 
						 | 
					@ -618,6 +618,16 @@ pub fn listDropAt(
 | 
				
			||||||
) callconv(.C) RocList {
 | 
					) callconv(.C) RocList {
 | 
				
			||||||
    const size = list.len();
 | 
					    const size = list.len();
 | 
				
			||||||
    const size_u64 = @as(u64, @intCast(size));
 | 
					    const size_u64 = @as(u64, @intCast(size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // NOTE
 | 
				
			||||||
 | 
					    // we need to return an empty list explicitly,
 | 
				
			||||||
 | 
					    // because we rely on the pointer field being null if the list is empty
 | 
				
			||||||
 | 
					    // which also requires duplicating the utils.decref call to spend the RC token
 | 
				
			||||||
 | 
					    if (size <= 1) {
 | 
				
			||||||
 | 
					        list.decref(alignment, element_width, elements_refcounted, dec);
 | 
				
			||||||
 | 
					        return RocList.empty();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If droping the first or last element, return a seamless slice.
 | 
					    // If droping the first or last element, return a seamless slice.
 | 
				
			||||||
    // For simplicity, do this by calling listSublist.
 | 
					    // For simplicity, do this by calling listSublist.
 | 
				
			||||||
    // In the future, we can test if it is faster to manually inline the important parts here.
 | 
					    // In the future, we can test if it is faster to manually inline the important parts here.
 | 
				
			||||||
| 
						 | 
					@ -638,25 +648,16 @@ pub fn listDropAt(
 | 
				
			||||||
        // were >= than `size`, and we know `size` fits in usize.
 | 
					        // were >= than `size`, and we know `size` fits in usize.
 | 
				
			||||||
        const drop_index: usize = @intCast(drop_index_u64);
 | 
					        const drop_index: usize = @intCast(drop_index_u64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (list.isUnique()) {
 | 
				
			||||||
            if (elements_refcounted) {
 | 
					            if (elements_refcounted) {
 | 
				
			||||||
                const element = source_ptr + drop_index * element_width;
 | 
					                const element = source_ptr + drop_index * element_width;
 | 
				
			||||||
                dec(element);
 | 
					                dec(element);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // NOTE
 | 
					            const copy_target = source_ptr + (drop_index * element_width);
 | 
				
			||||||
        // we need to return an empty list explicitly,
 | 
					 | 
				
			||||||
        // because we rely on the pointer field being null if the list is empty
 | 
					 | 
				
			||||||
        // which also requires duplicating the utils.decref call to spend the RC token
 | 
					 | 
				
			||||||
        if (size < 2) {
 | 
					 | 
				
			||||||
            list.decref(alignment, element_width, elements_refcounted, dec);
 | 
					 | 
				
			||||||
            return RocList.empty();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (list.isUnique()) {
 | 
					 | 
				
			||||||
            var i = drop_index;
 | 
					 | 
				
			||||||
            const copy_target = source_ptr;
 | 
					 | 
				
			||||||
            const copy_source = copy_target + element_width;
 | 
					            const copy_source = copy_target + element_width;
 | 
				
			||||||
            std.mem.copyForwards(u8, copy_target[i..size], copy_source[i..size]);
 | 
					            const copy_size = (size - drop_index - 1) * element_width;
 | 
				
			||||||
 | 
					            std.mem.copyForwards(u8, copy_target[0..copy_size], copy_source[0..copy_size]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var new_list = list;
 | 
					            var new_list = list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue