mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +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,
|
&layout_interner,
|
||||||
module_id,
|
module_id,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
state.target_info,
|
|
||||||
&mut update_mode_ids,
|
&mut update_mode_ids,
|
||||||
&mut state.procedures,
|
&mut state.procedures,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ fn specialize_list<'a, 'i>(
|
||||||
environment: &mut DropSpecializationEnvironment<'a>,
|
environment: &mut DropSpecializationEnvironment<'a>,
|
||||||
incremented_children: &mut CountingMap<Child>,
|
incremented_children: &mut CountingMap<Child>,
|
||||||
symbol: &Symbol,
|
symbol: &Symbol,
|
||||||
item_layout: InLayout,
|
item_layout: InLayout<'a>,
|
||||||
continuation: &'a Stmt<'a>,
|
continuation: &'a Stmt<'a>,
|
||||||
) -> &'a Stmt<'a> {
|
) -> &'a Stmt<'a> {
|
||||||
let current_length = environment.list_length.get(symbol).copied();
|
let current_length = environment.list_length.get(symbol).copied();
|
||||||
|
@ -1138,11 +1138,11 @@ fn specialize_list<'a, 'i>(
|
||||||
layout_interner.contains_refcounted(item_layout),
|
layout_interner.contains_refcounted(item_layout),
|
||||||
current_length,
|
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)) => {
|
(true, Some(length)) => {
|
||||||
match environment.list_children.get(symbol) {
|
match environment.list_children.get(symbol) {
|
||||||
// Only specialize lists if all children are known.
|
Some(children) => {
|
||||||
// Otherwise we might have to insert an unbouned number of decrements.
|
|
||||||
Some(children) if children.len() as u64 == length => {
|
|
||||||
// TODO perhaps this allocation can be avoided.
|
// TODO perhaps this allocation can be avoided.
|
||||||
let children_clone = children.clone();
|
let children_clone = children.clone();
|
||||||
|
|
||||||
|
@ -1182,16 +1182,55 @@ fn specialize_list<'a, 'i>(
|
||||||
|
|
||||||
// Reversed to ensure that the generated code decrements the items in the correct order.
|
// Reversed to ensure that the generated code decrements the items in the correct order.
|
||||||
for i in (0..length).rev() {
|
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 {
|
if !*popped {
|
||||||
// Decrement the children that were not incremented before. And thus don't cancel out.
|
// Decrement the children that were not incremented before. And thus don't cancel out.
|
||||||
newer_continuation = arena
|
newer_continuation = arena.alloc(Stmt::Refcounting(
|
||||||
.alloc(Stmt::Refcounting(ModifyRc::Dec(*s), newer_continuation));
|
ModifyRc::Dec(*s),
|
||||||
|
newer_continuation,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do nothing for the children that were incremented before, as the decrement will cancel out.
|
// 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));
|
||||||
|
|
||||||
|
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
|
newer_continuation
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::collections::CollectIn;
|
use bumpalo::collections::CollectIn;
|
||||||
use roc_collections::{MutMap, MutSet};
|
use roc_collections::{MutMap, MutSet};
|
||||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||||
use roc_target::TargetInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert reset and reuse operations into the IR.
|
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>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
ident_ids: &'i mut IdentIds,
|
ident_ids: &'i mut IdentIds,
|
||||||
target_info: TargetInfo,
|
|
||||||
update_mode_ids: &'i mut UpdateModeIds,
|
update_mode_ids: &'i mut UpdateModeIds,
|
||||||
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||||
) {
|
) {
|
||||||
|
@ -46,7 +44,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
global_layouts.clone(),
|
global_layouts.clone(),
|
||||||
proc.clone(),
|
proc.clone(),
|
||||||
|
@ -60,7 +57,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
||||||
layout_interner: &'i STLayoutInterner<'a>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
ident_ids: &'i mut IdentIds,
|
ident_ids: &'i mut IdentIds,
|
||||||
target_info: TargetInfo,
|
|
||||||
update_mode_ids: &'i mut UpdateModeIds,
|
update_mode_ids: &'i mut UpdateModeIds,
|
||||||
mut symbol_layout: SymbolLayout<'a>,
|
mut symbol_layout: SymbolLayout<'a>,
|
||||||
mut proc: Proc<'a>,
|
mut proc: Proc<'a>,
|
||||||
|
@ -82,7 +78,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut env,
|
&mut env,
|
||||||
arena.alloc(proc.body),
|
arena.alloc(proc.body),
|
||||||
|
@ -100,7 +95,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner: &'i STLayoutInterner<'a>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
ident_ids: &'i mut IdentIds,
|
ident_ids: &'i mut IdentIds,
|
||||||
target_info: TargetInfo,
|
|
||||||
update_mode_ids: &'i mut UpdateModeIds,
|
update_mode_ids: &'i mut UpdateModeIds,
|
||||||
environment: &mut ReuseEnvironment<'a>,
|
environment: &mut ReuseEnvironment<'a>,
|
||||||
stmt: &'a Stmt<'a>,
|
stmt: &'a Stmt<'a>,
|
||||||
|
@ -145,7 +139,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
// See if we have a token.
|
// See if we have a token.
|
||||||
match environment.pop_reuse_token(&get_reuse_layout_info(
|
match environment.pop_reuse_token(&get_reuse_layout_info(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
target_info,
|
|
||||||
union_layout,
|
union_layout,
|
||||||
)) {
|
)) {
|
||||||
// We have a reuse token for this layout, use it.
|
// We have a reuse token for this layout, use it.
|
||||||
|
@ -214,7 +207,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
current_stmt,
|
current_stmt,
|
||||||
|
@ -258,7 +250,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut branch_env,
|
&mut branch_env,
|
||||||
branch,
|
branch,
|
||||||
|
@ -286,7 +277,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut branch_env,
|
&mut branch_env,
|
||||||
branch,
|
branch,
|
||||||
|
@ -428,11 +418,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
|
|
||||||
environment.push_reuse_token(
|
environment.push_reuse_token(
|
||||||
arena,
|
arena,
|
||||||
get_reuse_layout_info(
|
get_reuse_layout_info(layout_interner, union_layout),
|
||||||
layout_interner,
|
|
||||||
target_info,
|
|
||||||
union_layout,
|
|
||||||
),
|
|
||||||
reuse_token,
|
reuse_token,
|
||||||
layout,
|
layout,
|
||||||
);
|
);
|
||||||
|
@ -451,7 +437,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
continuation,
|
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 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 {
|
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(
|
let stack_reuse_token = environment
|
||||||
layout_interner,
|
.peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
||||||
target_info,
|
|
||||||
union_layout,
|
|
||||||
));
|
|
||||||
|
|
||||||
match stack_reuse_token {
|
match stack_reuse_token {
|
||||||
Some(token_with_layout) if token_with_layout.token == 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.
|
// 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.
|
// 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(
|
let _ = environment
|
||||||
layout_interner,
|
.pop_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
||||||
target_info,
|
|
||||||
union_layout,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// The token we inserted is no longer on the stack, it must have been consumed.
|
// 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,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -551,7 +529,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -575,7 +552,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -611,7 +587,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut first_pass_environment,
|
&mut first_pass_environment,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -693,7 +668,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut first_pass_body_environment,
|
&mut first_pass_body_environment,
|
||||||
body,
|
body,
|
||||||
|
@ -784,7 +758,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
environment,
|
environment,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -871,7 +844,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
target_info,
|
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
&mut body_environment,
|
&mut body_environment,
|
||||||
body,
|
body,
|
||||||
|
@ -1340,10 +1312,10 @@ fn drop_unused_reuse_tokens<'a>(
|
||||||
|
|
||||||
fn get_reuse_layout_info<'a, 'i>(
|
fn get_reuse_layout_info<'a, 'i>(
|
||||||
layout_interner: &'i STLayoutInterner<'a>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
target_info: TargetInfo,
|
|
||||||
union_layout: UnionLayout<'a>,
|
union_layout: UnionLayout<'a>,
|
||||||
) -> TokenLayout {
|
) -> 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 {
|
let has_tag = match union_layout {
|
||||||
UnionLayout::NonRecursive(_) => unreachable!("Non recursive unions should not be reused."),
|
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.
|
// 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