mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
cleanup
This commit is contained in:
parent
cc9873eb6d
commit
a170f461e0
2 changed files with 2 additions and 146 deletions
|
@ -427,51 +427,6 @@ pub fn canonicalize_defs<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crawl_for_references(
|
|
||||||
home: ModuleId,
|
|
||||||
input_references: References,
|
|
||||||
refs_by_def: &MutMap<Symbol, (Region, References)>,
|
|
||||||
closures: &MutMap<Symbol, References>,
|
|
||||||
) -> References {
|
|
||||||
// Determine the full set of references by traversing the graph.
|
|
||||||
let mut visited_symbols = MutSet::default();
|
|
||||||
let returned_lookups = ImSet::clone(&input_references.value_lookups);
|
|
||||||
|
|
||||||
let mut output_references = input_references;
|
|
||||||
|
|
||||||
// Start with the return expression's referenced locals. They're the only ones that count!
|
|
||||||
//
|
|
||||||
// If I have two defs which reference each other, but neither of them is referenced
|
|
||||||
// in the return expression, I don't want either of them (or their references) to end up
|
|
||||||
// in the final output.references. They were unused, and so were their references!
|
|
||||||
//
|
|
||||||
// The reason we need a graph here is so we don't overlook transitive dependencies.
|
|
||||||
// For example, if I have `a = b + 1` and the def returns `a + 1`, then the
|
|
||||||
// def as a whole references both `a` *and* `b`, even though it doesn't
|
|
||||||
// directly mention `b` - because `a` depends on `b`. If we didn't traverse a graph here,
|
|
||||||
// we'd erroneously give a warning that `b` was unused since it wasn't directly referenced.
|
|
||||||
for symbol in returned_lookups.into_iter() {
|
|
||||||
// We only care about local symbols in this analysis.
|
|
||||||
if symbol.module_id() == home {
|
|
||||||
// Traverse the graph and look up *all* the references for this local symbol.
|
|
||||||
let refs = references_from_local(symbol, &mut visited_symbols, refs_by_def, closures);
|
|
||||||
|
|
||||||
output_references = output_references.union(refs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for symbol in ImSet::clone(&output_references.calls).into_iter() {
|
|
||||||
// Traverse the graph and look up *all* the references for this call.
|
|
||||||
// Reuse the same visited_symbols as before; if we already visited it,
|
|
||||||
// we won't learn anything new from visiting it again!
|
|
||||||
let refs = references_from_call(symbol, &mut visited_symbols, refs_by_def, closures);
|
|
||||||
|
|
||||||
output_references = output_references.union(refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
output_references
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_used_defs(
|
fn find_used_defs(
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
value_lookups: &ImSet<Symbol>,
|
value_lookups: &ImSet<Symbol>,
|
||||||
|
@ -535,10 +490,8 @@ pub fn sort_can_defs(
|
||||||
}
|
}
|
||||||
|
|
||||||
let initial = output.references.clone();
|
let initial = output.references.clone();
|
||||||
let initial1 = output.references.clone();
|
|
||||||
let initial2 = output.references.clone();
|
|
||||||
|
|
||||||
let b = initial2.union(find_used_defs(
|
let b = initial.union(find_used_defs(
|
||||||
env.home,
|
env.home,
|
||||||
&output.references.value_lookups,
|
&output.references.value_lookups,
|
||||||
&output.references.calls,
|
&output.references.calls,
|
||||||
|
@ -546,16 +499,7 @@ pub fn sort_can_defs(
|
||||||
&env.closures,
|
&env.closures,
|
||||||
));
|
));
|
||||||
|
|
||||||
let a = output.references.union(crawl_for_references(
|
output.references = b;
|
||||||
env.home,
|
|
||||||
initial,
|
|
||||||
&refs_by_symbol,
|
|
||||||
&env.closures,
|
|
||||||
));
|
|
||||||
|
|
||||||
assert!(a == b);
|
|
||||||
|
|
||||||
output.references = a;
|
|
||||||
|
|
||||||
let mut defined_symbols: Vec<Symbol> = Vec::new();
|
let mut defined_symbols: Vec<Symbol> = Vec::new();
|
||||||
let mut defined_symbols_set: ImSet<Symbol> = ImSet::default();
|
let mut defined_symbols_set: ImSet<Symbol> = ImSet::default();
|
||||||
|
|
|
@ -1251,94 +1251,6 @@ where
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn references_from_local<'a, T>(
|
|
||||||
defined_symbol: Symbol,
|
|
||||||
visited: &'a mut MutSet<Symbol>,
|
|
||||||
refs_by_def: &'a MutMap<Symbol, (T, References)>,
|
|
||||||
closures: &'a MutMap<Symbol, References>,
|
|
||||||
) -> References
|
|
||||||
where
|
|
||||||
T: Debug,
|
|
||||||
{
|
|
||||||
let mut answer: References = References::new();
|
|
||||||
|
|
||||||
match refs_by_def.get(&defined_symbol) {
|
|
||||||
Some((_, refs)) => {
|
|
||||||
visited.insert(defined_symbol);
|
|
||||||
|
|
||||||
for local in refs.value_lookups.iter() {
|
|
||||||
if !visited.contains(local) {
|
|
||||||
let other_refs: References =
|
|
||||||
references_from_local(*local, visited, refs_by_def, closures);
|
|
||||||
|
|
||||||
answer = answer.union(other_refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer.value_lookups.insert(*local);
|
|
||||||
}
|
|
||||||
|
|
||||||
for call in refs.calls.iter() {
|
|
||||||
if !visited.contains(call) {
|
|
||||||
let other_refs = references_from_call(*call, visited, refs_by_def, closures);
|
|
||||||
|
|
||||||
answer = answer.union(other_refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer.calls.insert(*call);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer
|
|
||||||
}
|
|
||||||
None => answer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn references_from_call<'a, T>(
|
|
||||||
call_symbol: Symbol,
|
|
||||||
visited: &'a mut MutSet<Symbol>,
|
|
||||||
refs_by_def: &'a MutMap<Symbol, (T, References)>,
|
|
||||||
closures: &'a MutMap<Symbol, References>,
|
|
||||||
) -> References
|
|
||||||
where
|
|
||||||
T: Debug,
|
|
||||||
{
|
|
||||||
match closures.get(&call_symbol) {
|
|
||||||
Some(references) => {
|
|
||||||
let mut answer = references.clone();
|
|
||||||
|
|
||||||
visited.insert(call_symbol);
|
|
||||||
|
|
||||||
for closed_over_local in references.value_lookups.iter() {
|
|
||||||
if !visited.contains(closed_over_local) {
|
|
||||||
let other_refs =
|
|
||||||
references_from_local(*closed_over_local, visited, refs_by_def, closures);
|
|
||||||
|
|
||||||
answer = answer.union(other_refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer.value_lookups.insert(*closed_over_local);
|
|
||||||
}
|
|
||||||
|
|
||||||
for call in references.calls.iter() {
|
|
||||||
if !visited.contains(call) {
|
|
||||||
let other_refs = references_from_call(*call, visited, refs_by_def, closures);
|
|
||||||
|
|
||||||
answer = answer.union(other_refs);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer.calls.insert(*call);
|
|
||||||
}
|
|
||||||
|
|
||||||
answer
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
// If the call symbol was not in the closure map, that means we're calling a non-function and
|
|
||||||
// will get a type mismatch later. For now, assume no references as a result of the "call."
|
|
||||||
References::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CanonicalizeRecordProblem {
|
enum CanonicalizeRecordProblem {
|
||||||
InvalidOptionalValue {
|
InvalidOptionalValue {
|
||||||
field_name: Lowercase,
|
field_name: Lowercase,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue