fix: A unique error was caused by the order in which we insert functions.

These functions relied on the same dependency and had the same scope. So insertion was by encounter rather than order determined by dependency handling. Now we switched to dependency order is prioritized to prevent free unique.
This commit is contained in:
Kasey White 2023-03-01 13:02:04 -05:00 committed by Kasey
parent e14048fdbb
commit d7c33bd62a
2 changed files with 32 additions and 24 deletions

View File

@ -1827,26 +1827,26 @@ pub fn monomorphize(
pub fn handle_func_dependencies_ir( pub fn handle_func_dependencies_ir(
dependencies_ir: &mut Vec<Air>, dependencies_ir: &mut Vec<Air>,
funt_comp: &FuncComponents, function_component: &FuncComponents,
func_components: &IndexMap<FunctionAccessKey, FuncComponents>, func_components: &IndexMap<FunctionAccessKey, FuncComponents>,
defined_functions: &mut IndexMap<FunctionAccessKey, ()>, defined_functions: &mut IndexMap<FunctionAccessKey, ()>,
func_index_map: &IndexMap<FunctionAccessKey, Vec<u64>>, func_index_map: &IndexMap<FunctionAccessKey, Vec<u64>>,
func_scope: &[u64], func_scope: &[u64],
to_be_defined: &mut IndexMap<FunctionAccessKey, ()>, to_be_defined: &mut IndexMap<FunctionAccessKey, ()>,
) { ) {
let mut funt_comp = funt_comp.clone(); let mut function_component = function_component.clone();
let mut dependency_map = IndexMap::new(); let mut dependency_map = IndexMap::new();
let mut dependency_vec = vec![]; let mut dependency_vec = vec![];
// deal with function dependencies by sorting order in which we pop them. // deal with function dependencies by sorting order in which we pop them.
while let Some(dependency) = funt_comp.dependencies.pop() { while let Some(dependency) = function_component.dependencies.pop() {
let depend_comp = func_components.get(&dependency).unwrap(); let depend_comp = func_components.get(&dependency).unwrap();
if dependency_map.contains_key(&dependency) { if dependency_map.contains_key(&dependency) {
dependency_map.shift_remove(&dependency); dependency_map.shift_remove(&dependency);
} }
dependency_map.insert(dependency, ()); dependency_map.insert(dependency, ());
funt_comp function_component
.dependencies .dependencies
.extend(depend_comp.dependencies.clone().into_iter()); .extend(depend_comp.dependencies.clone().into_iter());
} }
@ -1864,7 +1864,7 @@ pub fn handle_func_dependencies_ir(
let dep_scope = func_index_map.get(&dependency).unwrap(); let dep_scope = func_index_map.get(&dependency).unwrap();
if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec() if get_common_ancestor(dep_scope, func_scope) == func_scope.to_vec()
|| funt_comp.args.is_empty() || function_component.args.is_empty()
{ {
let mut recursion_ir = vec![]; let mut recursion_ir = vec![];
handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir); handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir);

View File

@ -2941,14 +2941,14 @@ impl<'a> CodeGenerator<'a> {
} }
fn define_ir(&mut self, ir_stack: &mut Vec<Air>) { fn define_ir(&mut self, ir_stack: &mut Vec<Air>) {
let mut func_components = IndexMap::new(); let mut function_definitions = IndexMap::new();
let mut func_index_map = IndexMap::new(); let mut func_index_map = IndexMap::new();
let recursion_func_map = IndexMap::new(); let recursion_func_map = IndexMap::new();
self.define_ir_recurse( self.define_ir_recurse(
ir_stack, ir_stack,
&mut func_components, &mut function_definitions,
&mut func_index_map, &mut func_index_map,
recursion_func_map, recursion_func_map,
false, false,
@ -2960,7 +2960,7 @@ impl<'a> CodeGenerator<'a> {
let mut dependency_map = IndexMap::new(); let mut dependency_map = IndexMap::new();
let mut dependency_vec = vec![]; let mut dependency_vec = vec![];
let mut func_keys = func_components let mut func_keys = function_definitions
.clone() .clone()
.into_iter() .into_iter()
.filter(|(_, val)| !val.defined_by_zero_arg) .filter(|(_, val)| !val.defined_by_zero_arg)
@ -2969,7 +2969,7 @@ impl<'a> CodeGenerator<'a> {
// deal with function dependencies by sorting order in which we iter over them. // deal with function dependencies by sorting order in which we iter over them.
while let Some(function) = func_keys.pop() { while let Some(function) = func_keys.pop() {
let funct_comp = func_components.get(&function.0).unwrap(); let funct_comp = function_definitions.get(&function.0).unwrap();
if dependency_map.contains_key(&function.0) { if dependency_map.contains_key(&function.0) {
dependency_map.shift_remove(&function.0); dependency_map.shift_remove(&function.0);
} }
@ -2981,7 +2981,7 @@ impl<'a> CodeGenerator<'a> {
.map(|key| { .map(|key| {
( (
key.clone(), key.clone(),
func_components.get(key).unwrap().defined_by_zero_arg, function_definitions.get(key).unwrap().defined_by_zero_arg,
) )
}) })
.collect_vec(), .collect_vec(),
@ -3000,17 +3000,17 @@ impl<'a> CodeGenerator<'a> {
if self.defined_functions.contains_key(&func) { if self.defined_functions.contains_key(&func) {
continue; continue;
} }
let funt_comp = func_components.get(&func).unwrap(); let function_component = function_definitions.get(&func).unwrap();
let func_scope = func_index_map.get(&func).unwrap(); let func_scope = func_index_map.get(&func).unwrap();
let mut dep_ir = vec![]; let mut dep_ir = vec![];
if !funt_comp.args.is_empty() { if !function_component.args.is_empty() {
// deal with function dependencies // deal with function dependencies
handle_func_dependencies_ir( handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
funt_comp, function_component,
&func_components, &function_definitions,
&mut self.defined_functions, &mut self.defined_functions,
&func_index_map, &func_index_map,
func_scope, func_scope,
@ -3025,8 +3025,8 @@ impl<'a> CodeGenerator<'a> {
// deal with function dependencies in zero arg functions // deal with function dependencies in zero arg functions
handle_func_dependencies_ir( handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
funt_comp, function_component,
&func_components, &function_definitions,
&mut defined_functions, &mut defined_functions,
&func_index_map, &func_index_map,
func_scope, func_scope,
@ -3034,7 +3034,7 @@ impl<'a> CodeGenerator<'a> {
); );
let mut final_zero_arg_ir = dep_ir; let mut final_zero_arg_ir = dep_ir;
final_zero_arg_ir.extend(funt_comp.ir.clone()); final_zero_arg_ir.extend(function_component.ir.clone());
self.convert_opaque_type_to_inner_ir(&mut final_zero_arg_ir); self.convert_opaque_type_to_inner_ir(&mut final_zero_arg_ir);
@ -3047,15 +3047,15 @@ impl<'a> CodeGenerator<'a> {
while let Some(func) = to_be_defined.pop() { while let Some(func) = to_be_defined.pop() {
let mut dep_ir = vec![]; let mut dep_ir = vec![];
let mut defined_functions = IndexMap::new(); let mut defined_functions = IndexMap::new();
// deal with function dependencies in zero arg functions
let funt_comp = func_components.get(&func.0).unwrap(); // deal with function dependencies in zero arg functions
let funt_comp = function_definitions.get(&func.0).unwrap();
let func_scope = func_index_map.get(&func.0).unwrap(); let func_scope = func_index_map.get(&func.0).unwrap();
handle_func_dependencies_ir( handle_func_dependencies_ir(
&mut dep_ir, &mut dep_ir,
funt_comp, funt_comp,
&func_components, &function_definitions,
&mut defined_functions, &mut defined_functions,
&func_index_map, &func_index_map,
func_scope, func_scope,
@ -3073,8 +3073,13 @@ impl<'a> CodeGenerator<'a> {
for (index, ir) in ir_stack.clone().into_iter().enumerate().rev() { for (index, ir) in ir_stack.clone().into_iter().enumerate().rev() {
{ {
let temp_func_index_map = func_index_map.clone(); let temp_func_index_map = func_index_map.clone();
let to_insert = temp_func_index_map let to_insert = final_func_dep_ir
.into_iter() .iter()
.filter_map(|(func_key, _)| {
temp_func_index_map
.get(func_key)
.map(|scope| (func_key.clone(), scope.clone()))
})
.filter(|func| { .filter(|func| {
get_common_ancestor(&func.1, &ir.scope()) == ir.scope() get_common_ancestor(&func.1, &ir.scope()) == ir.scope()
&& !self.defined_functions.contains_key(&func.0) && !self.defined_functions.contains_key(&func.0)
@ -3083,7 +3088,7 @@ impl<'a> CodeGenerator<'a> {
}) })
.collect_vec(); .collect_vec();
for (function_access_key, scopes) in to_insert.into_iter() { for (function_access_key, scopes) in to_insert.into_iter().rev() {
func_index_map.remove(&function_access_key); func_index_map.remove(&function_access_key);
self.defined_functions self.defined_functions
@ -3092,7 +3097,10 @@ impl<'a> CodeGenerator<'a> {
let mut full_func_ir = let mut full_func_ir =
final_func_dep_ir.get(&function_access_key).unwrap().clone(); final_func_dep_ir.get(&function_access_key).unwrap().clone();
let func_comp = func_components.get(&function_access_key).unwrap().clone(); let func_comp = function_definitions
.get(&function_access_key)
.unwrap()
.clone();
// zero arg functions are not recursive // zero arg functions are not recursive
if !func_comp.args.is_empty() { if !func_comp.args.is_empty() {