diff --git a/compiler/can/src/def.rs b/compiler/can/src/def.rs index c5c5dd3b15..5e5430eabc 100644 --- a/compiler/can/src/def.rs +++ b/compiler/can/src/def.rs @@ -427,51 +427,6 @@ pub fn canonicalize_defs<'a>( ) } -fn crawl_for_references( - home: ModuleId, - input_references: References, - refs_by_def: &MutMap, - closures: &MutMap, -) -> 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( home: ModuleId, value_lookups: &ImSet, @@ -535,10 +490,8 @@ pub fn sort_can_defs( } 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, &output.references.value_lookups, &output.references.calls, @@ -546,16 +499,7 @@ pub fn sort_can_defs( &env.closures, )); - let a = output.references.union(crawl_for_references( - env.home, - initial, - &refs_by_symbol, - &env.closures, - )); - - assert!(a == b); - - output.references = a; + output.references = b; let mut defined_symbols: Vec = Vec::new(); let mut defined_symbols_set: ImSet = ImSet::default(); diff --git a/compiler/can/src/expr.rs b/compiler/can/src/expr.rs index 39f49d2483..65668696d0 100644 --- a/compiler/can/src/expr.rs +++ b/compiler/can/src/expr.rs @@ -1251,94 +1251,6 @@ where result } -pub(crate) fn references_from_local<'a, T>( - defined_symbol: Symbol, - visited: &'a mut MutSet, - refs_by_def: &'a MutMap, - closures: &'a MutMap, -) -> 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, - refs_by_def: &'a MutMap, - closures: &'a MutMap, -) -> 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 { InvalidOptionalValue { field_name: Lowercase,