mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge pull request #5548 from JTeeuwissen/fix-oc-test-panics-after-roc-check-said-zero-errors,-zero-warnings
Index array symbols unknown symbols
This commit is contained in:
commit
c907b12cf0
3 changed files with 57 additions and 47 deletions
|
@ -3131,7 +3131,6 @@ fn update<'a>(
|
|||
&layout_interner,
|
||||
module_id,
|
||||
ident_ids,
|
||||
state.target_info,
|
||||
&mut update_mode_ids,
|
||||
&mut state.procedures,
|
||||
);
|
||||
|
|
|
@ -1121,7 +1121,7 @@ fn specialize_list<'a, 'i>(
|
|||
environment: &mut DropSpecializationEnvironment<'a>,
|
||||
incremented_children: &mut CountingMap<Child>,
|
||||
symbol: &Symbol,
|
||||
item_layout: InLayout,
|
||||
item_layout: InLayout<'a>,
|
||||
continuation: &'a Stmt<'a>,
|
||||
) -> &'a Stmt<'a> {
|
||||
let current_length = environment.list_length.get(symbol).copied();
|
||||
|
@ -1138,11 +1138,11 @@ fn specialize_list<'a, 'i>(
|
|||
layout_interner.contains_refcounted(item_layout),
|
||||
current_length,
|
||||
) {
|
||||
// Only specialize lists if the amount of children is known.
|
||||
// Otherwise we might have to insert an unbouned number of decrements.
|
||||
(true, Some(length)) => {
|
||||
match environment.list_children.get(symbol) {
|
||||
// Only specialize lists if all children are known.
|
||||
// Otherwise we might have to insert an unbouned number of decrements.
|
||||
Some(children) if children.len() as u64 == length => {
|
||||
Some(children) => {
|
||||
// TODO perhaps this allocation can be avoided.
|
||||
let children_clone = children.clone();
|
||||
|
||||
|
@ -1182,15 +1182,54 @@ fn specialize_list<'a, 'i>(
|
|||
|
||||
// Reversed to ensure that the generated code decrements the items in the correct order.
|
||||
for i in (0..length).rev() {
|
||||
let (s, popped) = index_symbols.get(&i).unwrap();
|
||||
match index_symbols.get(&i) {
|
||||
// If the symbol is known, we can decrement it (if incremented before).
|
||||
Some((s, popped)) => {
|
||||
if !*popped {
|
||||
// Decrement the children that were not incremented before. And thus don't cancel out.
|
||||
newer_continuation = arena.alloc(Stmt::Refcounting(
|
||||
ModifyRc::Dec(*s),
|
||||
newer_continuation,
|
||||
));
|
||||
}
|
||||
|
||||
if !*popped {
|
||||
// Decrement the children that were not incremented before. And thus don't cancel out.
|
||||
newer_continuation = arena
|
||||
.alloc(Stmt::Refcounting(ModifyRc::Dec(*s), newer_continuation));
|
||||
}
|
||||
// Do nothing for the children that were incremented before, as the decrement will cancel out.
|
||||
}
|
||||
// If the symbol is unknown, we have to get the value from the list.
|
||||
// Should only happen when list elements are discarded.
|
||||
None => {
|
||||
let field_symbol = environment
|
||||
.create_symbol(ident_ids, &format!("field_val_{}", i));
|
||||
|
||||
// Do nothing for the children that were incremented before, as the decrement will cancel out.
|
||||
let index_symbol = environment
|
||||
.create_symbol(ident_ids, &format!("index_val_{}", i));
|
||||
|
||||
let dec = arena.alloc(Stmt::Refcounting(
|
||||
ModifyRc::Dec(field_symbol),
|
||||
newer_continuation,
|
||||
));
|
||||
|
||||
let index = arena.alloc(Stmt::Let(
|
||||
field_symbol,
|
||||
Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::ListGetUnsafe,
|
||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||
},
|
||||
arguments: arena.alloc([*symbol, index_symbol]),
|
||||
}),
|
||||
item_layout,
|
||||
dec,
|
||||
));
|
||||
|
||||
newer_continuation = arena.alloc(Stmt::Let(
|
||||
index_symbol,
|
||||
Expr::Literal(Literal::Int(i128::to_ne_bytes(i as i128))),
|
||||
Layout::isize(layout_interner.target_info()),
|
||||
index,
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
newer_continuation
|
||||
|
|
|
@ -20,7 +20,6 @@ use bumpalo::collections::vec::Vec;
|
|||
use bumpalo::collections::CollectIn;
|
||||
use roc_collections::{MutMap, MutSet};
|
||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
/**
|
||||
Insert reset and reuse operations into the IR.
|
||||
|
@ -31,7 +30,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
|||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
home: ModuleId,
|
||||
ident_ids: &'i mut IdentIds,
|
||||
target_info: TargetInfo,
|
||||
update_mode_ids: &'i mut UpdateModeIds,
|
||||
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) {
|
||||
|
@ -46,7 +44,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
global_layouts.clone(),
|
||||
proc.clone(),
|
||||
|
@ -60,7 +57,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
|||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
home: ModuleId,
|
||||
ident_ids: &'i mut IdentIds,
|
||||
target_info: TargetInfo,
|
||||
update_mode_ids: &'i mut UpdateModeIds,
|
||||
mut symbol_layout: SymbolLayout<'a>,
|
||||
mut proc: Proc<'a>,
|
||||
|
@ -82,7 +78,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut env,
|
||||
arena.alloc(proc.body),
|
||||
|
@ -100,7 +95,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
home: ModuleId,
|
||||
ident_ids: &'i mut IdentIds,
|
||||
target_info: TargetInfo,
|
||||
update_mode_ids: &'i mut UpdateModeIds,
|
||||
environment: &mut ReuseEnvironment<'a>,
|
||||
stmt: &'a Stmt<'a>,
|
||||
|
@ -145,7 +139,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
// See if we have a token.
|
||||
match environment.pop_reuse_token(&get_reuse_layout_info(
|
||||
layout_interner,
|
||||
target_info,
|
||||
union_layout,
|
||||
)) {
|
||||
// We have a reuse token for this layout, use it.
|
||||
|
@ -214,7 +207,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
current_stmt,
|
||||
|
@ -258,7 +250,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut branch_env,
|
||||
branch,
|
||||
|
@ -286,7 +277,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut branch_env,
|
||||
branch,
|
||||
|
@ -428,11 +418,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
|
||||
environment.push_reuse_token(
|
||||
arena,
|
||||
get_reuse_layout_info(
|
||||
layout_interner,
|
||||
target_info,
|
||||
union_layout,
|
||||
),
|
||||
get_reuse_layout_info(layout_interner, union_layout),
|
||||
reuse_token,
|
||||
layout,
|
||||
);
|
||||
|
@ -451,7 +437,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
continuation,
|
||||
|
@ -459,21 +444,15 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
|
||||
// If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed.
|
||||
if let Some((layout, union_layout, symbol, reuse_token, dec_ref)) = reuse_pair {
|
||||
let stack_reuse_token = environment.peek_reuse_token(&get_reuse_layout_info(
|
||||
layout_interner,
|
||||
target_info,
|
||||
union_layout,
|
||||
));
|
||||
let stack_reuse_token = environment
|
||||
.peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
||||
|
||||
match stack_reuse_token {
|
||||
Some(token_with_layout) if token_with_layout.token == reuse_token => {
|
||||
// The token we inserted is still on the stack, so we don't need to insert a reset operation.
|
||||
// We do need to remove the token from the environment. To prevent errors higher in the tree.
|
||||
let _ = environment.pop_reuse_token(&get_reuse_layout_info(
|
||||
layout_interner,
|
||||
target_info,
|
||||
union_layout,
|
||||
));
|
||||
let _ = environment
|
||||
.pop_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
||||
}
|
||||
_ => {
|
||||
// The token we inserted is no longer on the stack, it must have been consumed.
|
||||
|
@ -525,7 +504,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
remainder,
|
||||
|
@ -551,7 +529,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
remainder,
|
||||
|
@ -575,7 +552,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
remainder,
|
||||
|
@ -611,7 +587,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut first_pass_environment,
|
||||
remainder,
|
||||
|
@ -693,7 +668,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut first_pass_body_environment,
|
||||
body,
|
||||
|
@ -784,7 +758,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
environment,
|
||||
remainder,
|
||||
|
@ -871,7 +844,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
layout_interner,
|
||||
home,
|
||||
ident_ids,
|
||||
target_info,
|
||||
update_mode_ids,
|
||||
&mut body_environment,
|
||||
body,
|
||||
|
@ -1340,10 +1312,10 @@ fn drop_unused_reuse_tokens<'a>(
|
|||
|
||||
fn get_reuse_layout_info<'a, 'i>(
|
||||
layout_interner: &'i STLayoutInterner<'a>,
|
||||
target_info: TargetInfo,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> TokenLayout {
|
||||
let (size, alignment) = union_layout.data_size_and_alignment(layout_interner, target_info);
|
||||
let (size, alignment) =
|
||||
union_layout.data_size_and_alignment(layout_interner, layout_interner.target_info());
|
||||
let has_tag = match union_layout {
|
||||
UnionLayout::NonRecursive(_) => unreachable!("Non recursive unions should not be reused."),
|
||||
// The memory for union layouts that has a tag_id can be reused for new allocations with tag_id.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue