Add other shadowing cases

This commit is contained in:
Pi Lanningham 2023-08-07 16:23:28 -04:00 committed by Kasey
parent fc948f0029
commit dba0e11ba7
1 changed files with 86 additions and 45 deletions

View File

@ -583,22 +583,44 @@ pub fn erase_opaque_type_operations(
} }
} }
pub fn identify_recursive_static_params( /// Determine whether this air_tree node introduces any shadowing over `potential_matches`
air_tree: &mut AirTree, pub fn find_introduced_variables(air_tree: &AirTree) -> Vec<String> {
tree_path: &TreePath,
func_params: &Vec<String>,
func_key: &FunctionAccessKey,
variant: &String,
shadowed_parameters: &mut HashMap<String, TreePath>,
potential_recursive_statics: &mut Vec<String>
) {
match air_tree { match air_tree {
AirTree::Statement { statement: AirStatement::Let { name, .. }, .. } => { AirTree::Statement { statement: AirStatement::Let { name, .. }, .. } => vec![name.clone()],
if potential_recursive_statics.contains(name) { AirTree::Statement { statement: AirStatement::TupleGuard { indices, .. }, .. } |
shadowed_parameters.insert(name.clone(), tree_path.clone()); AirTree::Expression(AirExpression::TupleClause { indices, .. }) => {
} indices.iter().map(|(_, name)| name).cloned().collect()
}, },
AirTree::Expression(AirExpression::Call { func, args, .. }) => { AirTree::Expression(AirExpression::Fn { params, .. }) => {
params.iter().map(|name| name).cloned().collect()
},
AirTree::Statement { statement: AirStatement::ListAccessor { names, .. }, ..} => {
names.clone()
}
AirTree::Statement { statement: AirStatement::ListExpose { tail, tail_head_names, .. }, .. } => {
let mut ret = vec![];
if let Some((_, head)) = tail {
ret.push(head.clone())
}
for name in tail_head_names.iter().map(|(_, head)| head) {
ret.push(name.clone());
}
ret
},
AirTree::Statement { statement: AirStatement::TupleAccessor { names, .. }, .. } => {
names.clone()
},
AirTree::Statement { statement: AirStatement::FieldsExpose { indices, .. }, ..} => {
indices.iter().map(|(_, name, _)| name).cloned().collect()
}
_ => vec![]
}
}
/// Determine whether a function is recursive, and if so, get the arguments
pub fn is_recursive_function_call<'a>(air_tree: &'a AirTree, func_key: &FunctionAccessKey, variant: &String) -> (bool, Option<&'a Vec<AirTree>>) {
if let AirTree::Expression(AirExpression::Call { func, args, .. }) = air_tree {
if let AirTree::Expression(AirExpression::Var { if let AirTree::Expression(AirExpression::Var {
constructor: constructor:
ValueConstructor { ValueConstructor {
@ -610,8 +632,31 @@ pub fn identify_recursive_static_params(
}) = func.as_ref() { }) = func.as_ref() {
if name == &func_key.function_name if name == &func_key.function_name
&& module == &func_key.module_name && module == &func_key.module_name
&& variant == variant_name && variant == variant_name {
{ return (true, Some(args))
}
}
}
return (false, None)
}
pub fn identify_recursive_static_params(
air_tree: &mut AirTree,
tree_path: &TreePath,
func_params: &Vec<String>,
func_key: &FunctionAccessKey,
variant: &String,
shadowed_parameters: &mut HashMap<String, TreePath>,
potential_recursive_statics: &mut Vec<String>
) {
// Find whether any of the potential recursive statics get shadowed (because even if we pass in the same referenced name, it might not be static)
for introduced_variable in find_introduced_variables(air_tree) {
if potential_recursive_statics.contains(&introduced_variable) {
shadowed_parameters.insert(introduced_variable, tree_path.clone());
}
}
// Otherwise, if this is a recursive call site, disqualify anything that is different (or the same, but shadowed)
if let (true, Some(args)) = is_recursive_function_call(air_tree, func_key, variant) {
for (param, arg) in func_params.iter().zip(args) { for (param, arg) in func_params.iter().zip(args) {
if let Some((idx, _)) = potential_recursive_statics.iter().find_position(|&p| p == param) { if let Some((idx, _)) = potential_recursive_statics.iter().find_position(|&p| p == param) {
// Check if we pass something different in this recursive call site // Check if we pass something different in this recursive call site
@ -637,10 +682,6 @@ pub fn identify_recursive_static_params(
} }
} }
} }
}
},
_ => ()
}
} }
pub fn modify_self_calls(body: &mut AirTree, func_key: &FunctionAccessKey, variant: &String, func_params: &Vec<String>) -> Vec<String> { pub fn modify_self_calls(body: &mut AirTree, func_key: &FunctionAccessKey, variant: &String, func_params: &Vec<String>) -> Vec<String> {