mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Revert "Remove obsolete ListLenUsize"
This reverts commit ad1bca4ac9c40d336522f944df60d61a814435dd.
This commit is contained in:
parent
87d4760356
commit
739565e836
16 changed files with 64 additions and 29 deletions
|
@ -1121,7 +1121,7 @@ fn lowlevel_spec<'a>(
|
||||||
// just dream up a unit value
|
// just dream up a unit value
|
||||||
builder.add_make_tuple(block, &[])
|
builder.add_make_tuple(block, &[])
|
||||||
}
|
}
|
||||||
ListLen => {
|
ListLenUsize | ListLenU64 => {
|
||||||
// TODO should this touch the heap cell?
|
// TODO should this touch the heap cell?
|
||||||
// just dream up a unit value
|
// just dream up a unit value
|
||||||
builder.add_make_tuple(block, &[])
|
builder.add_make_tuple(block, &[])
|
||||||
|
|
|
@ -129,7 +129,8 @@ map_symbol_to_lowlevel_and_arity! {
|
||||||
StrWithCapacity; STR_WITH_CAPACITY; 1,
|
StrWithCapacity; STR_WITH_CAPACITY; 1,
|
||||||
StrReleaseExcessCapacity; STR_RELEASE_EXCESS_CAPACITY; 1,
|
StrReleaseExcessCapacity; STR_RELEASE_EXCESS_CAPACITY; 1,
|
||||||
|
|
||||||
ListLen; LIST_LEN; 1,
|
ListLenUsize; LIST_LEN_USIZE; 1,
|
||||||
|
ListLenU64; LIST_LEN_U64; 1,
|
||||||
ListWithCapacity; LIST_WITH_CAPACITY; 1,
|
ListWithCapacity; LIST_WITH_CAPACITY; 1,
|
||||||
ListReserve; LIST_RESERVE; 2,
|
ListReserve; LIST_RESERVE; 2,
|
||||||
ListIsUnique; LIST_IS_UNIQUE; 1,
|
ListIsUnique; LIST_IS_UNIQUE; 1,
|
||||||
|
|
|
@ -2830,7 +2830,12 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol) {
|
fn build_list_len_usize(&mut self, dst: &Symbol, list: &Symbol) {
|
||||||
|
self.storage_manager
|
||||||
|
.list_len_usize(&mut self.buf, dst, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_list_len_u64(&mut self, dst: &Symbol, list: &Symbol) {
|
||||||
self.storage_manager.list_len_u64(&mut self.buf, dst, list);
|
self.storage_manager.list_len_u64(&mut self.buf, dst, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1484,13 +1484,21 @@ trait Backend<'a> {
|
||||||
|
|
||||||
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
|
self.build_fn_call(sym, intrinsic.to_string(), args, arg_layouts, ret_layout)
|
||||||
}
|
}
|
||||||
LowLevel::ListLen => {
|
LowLevel::ListLenU64 => {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
1,
|
1,
|
||||||
args.len(),
|
args.len(),
|
||||||
"ListLenU64: expected to have exactly one argument"
|
"ListLenU64: expected to have exactly one argument"
|
||||||
);
|
);
|
||||||
self.build_list_len(sym, &args[0])
|
self.build_list_len_u64(sym, &args[0])
|
||||||
|
}
|
||||||
|
LowLevel::ListLenUsize => {
|
||||||
|
debug_assert_eq!(
|
||||||
|
1,
|
||||||
|
args.len(),
|
||||||
|
"ListLenUsize: expected to have exactly one argument"
|
||||||
|
);
|
||||||
|
self.build_list_len_usize(sym, &args[0])
|
||||||
}
|
}
|
||||||
LowLevel::ListWithCapacity => {
|
LowLevel::ListWithCapacity => {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -2374,8 +2382,11 @@ trait Backend<'a> {
|
||||||
/// build_sqrt stores the result of `sqrt(src)` into dst.
|
/// build_sqrt stores the result of `sqrt(src)` into dst.
|
||||||
fn build_num_sqrt(&mut self, dst: Symbol, src: Symbol, float_width: FloatWidth);
|
fn build_num_sqrt(&mut self, dst: Symbol, src: Symbol, float_width: FloatWidth);
|
||||||
|
|
||||||
/// build_list_len returns the length of a list after casting it from usize to u64.
|
/// build_list_len_usize returns the length of a list as a usize. This is for internal use only.
|
||||||
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol);
|
fn build_list_len_usize(&mut self, dst: &Symbol, list: &Symbol);
|
||||||
|
|
||||||
|
/// build_list_len_u64 returns the length of a list and casts it from usize to u64. This is for the public List.len.
|
||||||
|
fn build_list_len_u64(&mut self, dst: &Symbol, list: &Symbol);
|
||||||
|
|
||||||
/// generate a call to a higher-order lowlevel
|
/// generate a call to a higher-order lowlevel
|
||||||
fn build_higher_order_lowlevel(
|
fn build_higher_order_lowlevel(
|
||||||
|
|
|
@ -607,7 +607,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
bitcode::STR_WITH_CAPACITY,
|
bitcode::STR_WITH_CAPACITY,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ListLen => {
|
ListLenU64 => {
|
||||||
// List.len : List * -> U64
|
// List.len : List * -> U64
|
||||||
arguments!(list);
|
arguments!(list);
|
||||||
|
|
||||||
|
@ -618,6 +618,12 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
.new_build_int_cast(len_usize, env.context.i64_type(), "usize_to_u64")
|
.new_build_int_cast(len_usize, env.context.i64_type(), "usize_to_u64")
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
ListLenUsize => {
|
||||||
|
// List.lenUsize : List * -> usize # used internally, not exposed
|
||||||
|
arguments!(list);
|
||||||
|
|
||||||
|
list_len_usize(env.builder, list.into_struct_value()).into()
|
||||||
|
}
|
||||||
ListGetCapacity => {
|
ListGetCapacity => {
|
||||||
// List.capacity: List a -> U64
|
// List.capacity: List a -> U64
|
||||||
arguments!(list);
|
arguments!(list);
|
||||||
|
|
|
@ -260,13 +260,14 @@ impl<'a> LowLevelCall<'a> {
|
||||||
StrWithCapacity => self.load_args_and_call_zig(backend, bitcode::STR_WITH_CAPACITY),
|
StrWithCapacity => self.load_args_and_call_zig(backend, bitcode::STR_WITH_CAPACITY),
|
||||||
|
|
||||||
// List
|
// List
|
||||||
ListLen => {
|
ListLenU64 => {
|
||||||
self.load_list_len_usize(backend);
|
self.load_list_len_usize(backend);
|
||||||
|
|
||||||
// Length is stored as 32 bits in memory on wasm32,
|
// Length is stored as 32 bits in memory on wasm32,
|
||||||
// but List.len always returns U64
|
// but List.len always returns U64
|
||||||
backend.code_builder.i64_extend_u_i32();
|
backend.code_builder.i64_extend_u_i32();
|
||||||
}
|
}
|
||||||
|
ListLenUsize => self.load_list_len_usize(backend),
|
||||||
|
|
||||||
ListGetCapacity => self.load_args_and_call_zig(backend, bitcode::LIST_CAPACITY),
|
ListGetCapacity => self.load_args_and_call_zig(backend, bitcode::LIST_CAPACITY),
|
||||||
|
|
||||||
|
|
|
@ -4703,7 +4703,7 @@ fn synth_list_len_type(subs: &mut Subs) -> Variable {
|
||||||
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, a_slice)),
|
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, a_slice)),
|
||||||
);
|
);
|
||||||
let fn_var = synth_import(subs, Content::Error);
|
let fn_var = synth_import(subs, Content::Error);
|
||||||
let solved_list_len = UnionLabels::insert_into_subs(subs, [(Symbol::LIST_LEN, [])]);
|
let solved_list_len = UnionLabels::insert_into_subs(subs, [(Symbol::LIST_LEN_U64, [])]);
|
||||||
let clos_list_len = synth_import(
|
let clos_list_len = synth_import(
|
||||||
subs,
|
subs,
|
||||||
Content::LambdaSet(LambdaSet {
|
Content::LambdaSet(LambdaSet {
|
||||||
|
@ -4757,7 +4757,7 @@ pub fn add_imports(
|
||||||
// Num needs List.len, but List imports Num.
|
// Num needs List.len, but List imports Num.
|
||||||
let list_len_type_var = synth_list_len_type(subs);
|
let list_len_type_var = synth_list_len_type(subs);
|
||||||
let list_len_type_index = constraints.push_variable(list_len_type_var);
|
let list_len_type_index = constraints.push_variable(list_len_type_var);
|
||||||
def_types.push((Symbol::LIST_LEN, Loc::at_zero(list_len_type_index)));
|
def_types.push((Symbol::LIST_LEN_U64, Loc::at_zero(list_len_type_index)));
|
||||||
import_variables.push(list_len_type_var);
|
import_variables.push(list_len_type_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ pub enum LowLevel {
|
||||||
StrReserve,
|
StrReserve,
|
||||||
StrWithCapacity,
|
StrWithCapacity,
|
||||||
StrReleaseExcessCapacity,
|
StrReleaseExcessCapacity,
|
||||||
ListLen,
|
ListLenUsize,
|
||||||
|
ListLenU64,
|
||||||
ListWithCapacity,
|
ListWithCapacity,
|
||||||
ListReserve,
|
ListReserve,
|
||||||
ListReleaseExcessCapacity,
|
ListReleaseExcessCapacity,
|
||||||
|
@ -268,7 +269,8 @@ map_symbol_to_lowlevel! {
|
||||||
StrToNum <= STR_TO_NUM;
|
StrToNum <= STR_TO_NUM;
|
||||||
StrWithCapacity <= STR_WITH_CAPACITY;
|
StrWithCapacity <= STR_WITH_CAPACITY;
|
||||||
StrReleaseExcessCapacity <= STR_RELEASE_EXCESS_CAPACITY;
|
StrReleaseExcessCapacity <= STR_RELEASE_EXCESS_CAPACITY;
|
||||||
ListLen <= LIST_LEN;
|
ListLenU64 <= LIST_LEN_U64;
|
||||||
|
ListLenUsize <= LIST_LEN_USIZE;
|
||||||
ListGetCapacity <= LIST_CAPACITY;
|
ListGetCapacity <= LIST_CAPACITY;
|
||||||
ListWithCapacity <= LIST_WITH_CAPACITY;
|
ListWithCapacity <= LIST_WITH_CAPACITY;
|
||||||
ListReserve <= LIST_RESERVE;
|
ListReserve <= LIST_RESERVE;
|
||||||
|
|
|
@ -1342,7 +1342,7 @@ define_builtins! {
|
||||||
3 LIST_SET: "set"
|
3 LIST_SET: "set"
|
||||||
4 LIST_APPEND: "append"
|
4 LIST_APPEND: "append"
|
||||||
5 LIST_MAP: "map"
|
5 LIST_MAP: "map"
|
||||||
6 LIST_LEN: "len"
|
6 LIST_LEN_U64: "len"
|
||||||
7 LIST_WALK_BACKWARDS: "walkBackwards"
|
7 LIST_WALK_BACKWARDS: "walkBackwards"
|
||||||
8 LIST_CONCAT: "concat"
|
8 LIST_CONCAT: "concat"
|
||||||
9 LIST_FIRST: "first"
|
9 LIST_FIRST: "first"
|
||||||
|
@ -1424,6 +1424,7 @@ define_builtins! {
|
||||||
85 LIST_PREPEND_IF_OK: "prependIfOk"
|
85 LIST_PREPEND_IF_OK: "prependIfOk"
|
||||||
86 LIST_WALK_WITH_INDEX_UNTIL: "walkWithIndexUntil"
|
86 LIST_WALK_WITH_INDEX_UNTIL: "walkWithIndexUntil"
|
||||||
87 LIST_CLONE: "clone"
|
87 LIST_CLONE: "clone"
|
||||||
|
88 LIST_LEN_USIZE: "lenUsize"
|
||||||
}
|
}
|
||||||
7 RESULT: "Result" => {
|
7 RESULT: "Result" => {
|
||||||
0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias
|
0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias
|
||||||
|
|
|
@ -668,8 +668,8 @@ fn eq_list<'a>(
|
||||||
|
|
||||||
let len_1 = root.create_symbol(ident_ids, "len_1");
|
let len_1 = root.create_symbol(ident_ids, "len_1");
|
||||||
let len_2 = root.create_symbol(ident_ids, "len_2");
|
let len_2 = root.create_symbol(ident_ids, "len_2");
|
||||||
let len_1_stmt = |next| let_lowlevel(arena, Layout::U64, len_1, ListLen, &[ARG_1], next);
|
let len_1_stmt = |next| let_lowlevel(arena, layout_isize, len_1, ListLenUsize, &[ARG_1], next);
|
||||||
let len_2_stmt = |next| let_lowlevel(arena, Layout::U64, len_2, ListLen, &[ARG_2], next);
|
let len_2_stmt = |next| let_lowlevel(arena, layout_isize, len_2, ListLenUsize, &[ARG_2], next);
|
||||||
|
|
||||||
let eq_len = root.create_symbol(ident_ids, "eq_len");
|
let eq_len = root.create_symbol(ident_ids, "eq_len");
|
||||||
let eq_len_stmt = |next| let_lowlevel(arena, LAYOUT_BOOL, eq_len, Eq, &[len_1, len_2], next);
|
let eq_len_stmt = |next| let_lowlevel(arena, LAYOUT_BOOL, eq_len, Eq, &[len_1, len_2], next);
|
||||||
|
|
|
@ -926,12 +926,12 @@ fn refcount_list<'a>(
|
||||||
//
|
//
|
||||||
|
|
||||||
let len = root.create_symbol(ident_ids, "len");
|
let len = root.create_symbol(ident_ids, "len");
|
||||||
let len_stmt = |next| let_lowlevel(arena, Layout::U64, len, ListLen, &[structure], next);
|
let len_stmt = |next| let_lowlevel(arena, layout_isize, len, ListLenUsize, &[structure], next);
|
||||||
|
|
||||||
// let zero = 0
|
// let zero = 0
|
||||||
let zero = root.create_symbol(ident_ids, "zero");
|
let zero = root.create_symbol(ident_ids, "zero");
|
||||||
let zero_expr = Expr::Literal(Literal::Int(0i128.to_ne_bytes()));
|
let zero_expr = Expr::Literal(Literal::Int(0i128.to_ne_bytes()));
|
||||||
let zero_stmt = |next| Stmt::Let(zero, zero_expr, Layout::U64, next);
|
let zero_stmt = |next| Stmt::Let(zero, zero_expr, layout_isize, next);
|
||||||
|
|
||||||
// let is_empty = lowlevel Eq len zero
|
// let is_empty = lowlevel Eq len zero
|
||||||
let is_empty = root.create_symbol(ident_ids, "is_empty");
|
let is_empty = root.create_symbol(ident_ids, "is_empty");
|
||||||
|
|
|
@ -1533,8 +1533,8 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
||||||
|
|
||||||
match lowlevel {
|
match lowlevel {
|
||||||
Unreachable => RC::Uknown,
|
Unreachable => RC::Uknown,
|
||||||
ListLen | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity | ListWithCapacity
|
ListLenU64 | ListLenUsize | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity
|
||||||
| StrWithCapacity => RC::NoRc,
|
| ListWithCapacity | StrWithCapacity => RC::NoRc,
|
||||||
ListReplaceUnsafe => RC::Rc,
|
ListReplaceUnsafe => RC::Rc,
|
||||||
StrGetUnsafe | ListGetUnsafe => RC::NoRc,
|
StrGetUnsafe | ListGetUnsafe => RC::NoRc,
|
||||||
ListConcat => RC::Rc,
|
ListConcat => RC::Rc,
|
||||||
|
|
|
@ -1283,7 +1283,7 @@ fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
|
||||||
match op {
|
match op {
|
||||||
Unreachable => arena.alloc_slice_copy(&[irrelevant]),
|
Unreachable => arena.alloc_slice_copy(&[irrelevant]),
|
||||||
DictPseudoSeed => arena.alloc_slice_copy(&[irrelevant]),
|
DictPseudoSeed => arena.alloc_slice_copy(&[irrelevant]),
|
||||||
ListLen | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity => {
|
ListLenU64 | ListLenUsize | StrIsEmpty | StrCountUtf8Bytes | ListGetCapacity => {
|
||||||
arena.alloc_slice_copy(&[borrowed])
|
arena.alloc_slice_copy(&[borrowed])
|
||||||
}
|
}
|
||||||
ListWithCapacity | StrWithCapacity => arena.alloc_slice_copy(&[irrelevant]),
|
ListWithCapacity | StrWithCapacity => arena.alloc_slice_copy(&[irrelevant]),
|
||||||
|
|
|
@ -1769,7 +1769,7 @@ fn test_to_comparison<'a>(
|
||||||
LayoutRepr::Builtin(Builtin::List(_elem_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(_elem_layout)) => {
|
||||||
let real_len_expr = Expr::Call(Call {
|
let real_len_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::ListLen,
|
op: LowLevel::ListLenUsize,
|
||||||
update_mode: env.next_update_mode_id(),
|
update_mode: env.next_update_mode_id(),
|
||||||
},
|
},
|
||||||
arguments: env.arena.alloc([list_sym]),
|
arguments: env.arena.alloc([list_sym]),
|
||||||
|
@ -1779,8 +1779,10 @@ fn test_to_comparison<'a>(
|
||||||
let real_len = env.unique_symbol();
|
let real_len = env.unique_symbol();
|
||||||
let test_len = env.unique_symbol();
|
let test_len = env.unique_symbol();
|
||||||
|
|
||||||
stores.push((real_len, Layout::U64, real_len_expr));
|
let usize_layout = Layout::usize(env.target_info);
|
||||||
stores.push((test_len, Layout::U64, test_len_expr));
|
|
||||||
|
stores.push((real_len, usize_layout, real_len_expr));
|
||||||
|
stores.push((test_len, usize_layout, test_len_expr));
|
||||||
|
|
||||||
let comparison = match bound {
|
let comparison = match bound {
|
||||||
ListLenBound::Exact => (real_len, Comparator::Eq, test_len),
|
ListLenBound::Exact => (real_len, Comparator::Eq, test_len),
|
||||||
|
@ -2335,7 +2337,7 @@ fn decide_to_branching<'a>(
|
||||||
let len_symbol = env.unique_symbol();
|
let len_symbol = env.unique_symbol();
|
||||||
|
|
||||||
let switch = Stmt::Switch {
|
let switch = Stmt::Switch {
|
||||||
cond_layout: Layout::U64,
|
cond_layout: Layout::usize(env.target_info),
|
||||||
cond_symbol: len_symbol,
|
cond_symbol: len_symbol,
|
||||||
branches: branches.into_bump_slice(),
|
branches: branches.into_bump_slice(),
|
||||||
default_branch: (default_branch_info, env.arena.alloc(default_branch)),
|
default_branch: (default_branch_info, env.arena.alloc(default_branch)),
|
||||||
|
@ -2344,13 +2346,18 @@ fn decide_to_branching<'a>(
|
||||||
|
|
||||||
let len_expr = Expr::Call(Call {
|
let len_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::ListLen,
|
op: LowLevel::ListLenUsize,
|
||||||
update_mode: env.next_update_mode_id(),
|
update_mode: env.next_update_mode_id(),
|
||||||
},
|
},
|
||||||
arguments: env.arena.alloc([inner_cond_symbol]),
|
arguments: env.arena.alloc([inner_cond_symbol]),
|
||||||
});
|
});
|
||||||
|
|
||||||
Stmt::Let(len_symbol, len_expr, Layout::U64, env.arena.alloc(switch))
|
Stmt::Let(
|
||||||
|
len_symbol,
|
||||||
|
len_expr,
|
||||||
|
Layout::usize(env.target_info),
|
||||||
|
env.arena.alloc(switch),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
Stmt::Switch {
|
Stmt::Switch {
|
||||||
cond_layout: inner_cond_layout,
|
cond_layout: inner_cond_layout,
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ pub(crate) fn build_list_index_probe<'a>(
|
||||||
let len_sym = env.unique_symbol();
|
let len_sym = env.unique_symbol();
|
||||||
let len_expr = Expr::Call(Call {
|
let len_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::ListLen,
|
op: LowLevel::ListLenU64,
|
||||||
update_mode: env.next_update_mode_id(),
|
update_mode: env.next_update_mode_id(),
|
||||||
},
|
},
|
||||||
arguments: env.arena.alloc([list_sym]),
|
arguments: env.arena.alloc([list_sym]),
|
||||||
|
@ -1567,7 +1567,7 @@ fn store_list_rest<'a>(
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
// Must use ListLenU64 here because we're using it with List.sublist,
|
// Must use ListLenU64 here because we're using it with List.sublist,
|
||||||
// which takes U64s for start and len.
|
// which takes U64s for start and len.
|
||||||
op: LowLevel::ListLen,
|
op: LowLevel::ListLenU64,
|
||||||
update_mode: env.next_update_mode_id(),
|
update_mode: env.next_update_mode_id(),
|
||||||
},
|
},
|
||||||
arguments: env.arena.alloc([list_sym]),
|
arguments: env.arena.alloc([list_sym]),
|
||||||
|
|
|
@ -70,6 +70,7 @@ enum FirstOrder {
|
||||||
StrRepeat,
|
StrRepeat,
|
||||||
StrFromFloat,
|
StrFromFloat,
|
||||||
ListLenU64,
|
ListLenU64,
|
||||||
|
ListLenUsize,
|
||||||
ListGetUnsafe,
|
ListGetUnsafe,
|
||||||
ListSublist,
|
ListSublist,
|
||||||
ListDropAt,
|
ListDropAt,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue