mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge branch 'vecset-references' into builtins-in-roc
This commit is contained in:
commit
8692938fb3
18 changed files with 537 additions and 142 deletions
|
@ -16,6 +16,7 @@ pub struct MemberVariables {
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AbilityMemberData {
|
||||
pub parent_ability: Symbol,
|
||||
pub signature_var: Variable,
|
||||
pub signature: Type,
|
||||
pub variables: MemberVariables,
|
||||
pub region: Region,
|
||||
|
@ -60,15 +61,16 @@ impl AbilitiesStore {
|
|||
pub fn register_ability(
|
||||
&mut self,
|
||||
ability: Symbol,
|
||||
members: Vec<(Symbol, Region, Type, MemberVariables)>,
|
||||
members: Vec<(Symbol, Region, Variable, Type, MemberVariables)>,
|
||||
) {
|
||||
let mut members_vec = Vec::with_capacity(members.len());
|
||||
for (member, region, signature, variables) in members.into_iter() {
|
||||
for (member, region, signature_var, signature, variables) in members.into_iter() {
|
||||
members_vec.push(member);
|
||||
let old_member = self.ability_members.insert(
|
||||
member,
|
||||
AbilityMemberData {
|
||||
parent_ability: ability,
|
||||
signature_var,
|
||||
signature,
|
||||
region,
|
||||
variables,
|
||||
|
|
|
@ -542,7 +542,13 @@ pub fn canonicalize_defs<'a>(
|
|||
flex_vars: iv.collect_flex(),
|
||||
};
|
||||
|
||||
can_members.push((member_sym, name_region, member_annot.typ, variables));
|
||||
can_members.push((
|
||||
member_sym,
|
||||
name_region,
|
||||
var_store.fresh(),
|
||||
member_annot.typ,
|
||||
variables,
|
||||
));
|
||||
}
|
||||
|
||||
// Store what symbols a type must define implementations for to have this ability.
|
||||
|
@ -690,7 +696,7 @@ pub fn sort_can_defs(
|
|||
if let Some(References { value_lookups, .. }) = env.closures.get(symbol) {
|
||||
let home = env.home;
|
||||
|
||||
for lookup in value_lookups {
|
||||
for lookup in value_lookups.iter() {
|
||||
if lookup != symbol && lookup.module_id() == home {
|
||||
// DO NOT register a self-call behind a lambda!
|
||||
//
|
||||
|
@ -741,7 +747,7 @@ pub fn sort_can_defs(
|
|||
|
||||
// if the current symbol is a closure, peek into its body
|
||||
if let Some(References { value_lookups, .. }) = env.closures.get(symbol) {
|
||||
for lookup in value_lookups {
|
||||
for lookup in value_lookups.iter() {
|
||||
loc_succ.push(*lookup);
|
||||
}
|
||||
}
|
||||
|
@ -1306,7 +1312,7 @@ fn canonicalize_pending_value_def<'a>(
|
|||
let (mut loc_can_expr, can_output) =
|
||||
canonicalize_expr(env, var_store, scope, loc_expr.region, &loc_expr.value);
|
||||
|
||||
output.references = output.references.union(can_output.references.clone());
|
||||
output.references.union_mut(&can_output.references);
|
||||
|
||||
// reset the tailcallable_symbol
|
||||
env.tailcallable_symbol = outer_identifier;
|
||||
|
@ -1356,7 +1362,7 @@ fn canonicalize_pending_value_def<'a>(
|
|||
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
||||
// would result in circular def errors!)
|
||||
refs_by_symbol.entry(symbol).and_modify(|(_, refs)| {
|
||||
refs.value_lookups = refs.value_lookups.without(&symbol);
|
||||
refs.value_lookups.remove(&symbol);
|
||||
});
|
||||
|
||||
// renamed_closure_def = Some(&symbol);
|
||||
|
@ -1496,7 +1502,7 @@ fn canonicalize_pending_value_def<'a>(
|
|||
// Recursion doesn't count as referencing. (If it did, all recursive functions
|
||||
// would result in circular def errors!)
|
||||
refs_by_symbol.entry(symbol).and_modify(|(_, refs)| {
|
||||
refs.value_lookups = refs.value_lookups.without(&symbol);
|
||||
refs.value_lookups.remove(&symbol);
|
||||
});
|
||||
|
||||
loc_can_expr.value = Closure(ClosureData {
|
||||
|
@ -1586,7 +1592,7 @@ pub fn can_defs_with_return<'a>(
|
|||
output
|
||||
.introduced_variables
|
||||
.union(&defs_output.introduced_variables);
|
||||
output.references = output.references.union(defs_output.references);
|
||||
output.references.union_mut(&defs_output.references);
|
||||
|
||||
// Now that we've collected all the references, check to see if any of the new idents
|
||||
// we defined went unused by the return expression. If any were unused, report it.
|
||||
|
@ -1640,7 +1646,7 @@ fn closure_recursivity(symbol: Symbol, closures: &MutMap<Symbol, References>) ->
|
|||
let mut stack = Vec::new();
|
||||
|
||||
if let Some(references) = closures.get(&symbol) {
|
||||
for v in &references.calls {
|
||||
for v in references.calls.iter() {
|
||||
stack.push(*v);
|
||||
}
|
||||
|
||||
|
@ -1656,7 +1662,7 @@ fn closure_recursivity(symbol: Symbol, closures: &MutMap<Symbol, References>) ->
|
|||
// if it calls any functions
|
||||
if let Some(nested_references) = closures.get(&nested_symbol) {
|
||||
// add its called to the stack
|
||||
for v in &nested_references.calls {
|
||||
for v in nested_references.calls.iter() {
|
||||
stack.push(*v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ pub struct Output {
|
|||
|
||||
impl Output {
|
||||
pub fn union(&mut self, other: Self) {
|
||||
self.references.union_mut(other.references);
|
||||
self.references.union_mut(&other.references);
|
||||
|
||||
if let (None, Some(later)) = (self.tail_call, other.tail_call) {
|
||||
self.tail_call = Some(later);
|
||||
|
@ -354,7 +354,7 @@ pub fn canonicalize_expr<'a>(
|
|||
if let Var(symbol) = &can_update.value {
|
||||
match canonicalize_fields(env, var_store, scope, region, fields.items) {
|
||||
Ok((can_fields, mut output)) => {
|
||||
output.references = output.references.union(update_out.references);
|
||||
output.references.union_mut(&update_out.references);
|
||||
|
||||
let answer = Update {
|
||||
record_var: var_store.fresh(),
|
||||
|
@ -432,7 +432,7 @@ pub fn canonicalize_expr<'a>(
|
|||
let (can_expr, elem_out) =
|
||||
canonicalize_expr(env, var_store, scope, loc_elem.region, &loc_elem.value);
|
||||
|
||||
references = references.union(elem_out.references);
|
||||
references.union_mut(&elem_out.references);
|
||||
|
||||
can_elems.push(can_expr);
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ pub fn canonicalize_expr<'a>(
|
|||
canonicalize_expr(env, var_store, scope, loc_arg.region, &loc_arg.value);
|
||||
|
||||
args.push((var_store.fresh(), arg_expr));
|
||||
output.references = output.references.union(arg_out.references);
|
||||
output.references.union_mut(&arg_out.references);
|
||||
}
|
||||
|
||||
if let ast::Expr::OpaqueRef(name) = loc_fn.value {
|
||||
|
@ -753,7 +753,7 @@ pub fn canonicalize_expr<'a>(
|
|||
let (can_when_branch, branch_references) =
|
||||
canonicalize_when_branch(env, var_store, scope, region, *branch, &mut output);
|
||||
|
||||
output.references = output.references.union(branch_references);
|
||||
output.references.union_mut(&branch_references);
|
||||
|
||||
can_branches.push(can_when_branch);
|
||||
}
|
||||
|
@ -886,8 +886,8 @@ pub fn canonicalize_expr<'a>(
|
|||
|
||||
branches.push((loc_cond, loc_then));
|
||||
|
||||
output.references = output.references.union(cond_output.references);
|
||||
output.references = output.references.union(then_output.references);
|
||||
output.references.union_mut(&cond_output.references);
|
||||
output.references.union_mut(&then_output.references);
|
||||
}
|
||||
|
||||
let (loc_else, else_output) = canonicalize_expr(
|
||||
|
@ -898,7 +898,7 @@ pub fn canonicalize_expr<'a>(
|
|||
&final_else_branch.value,
|
||||
);
|
||||
|
||||
output.references = output.references.union(else_output.references);
|
||||
output.references.union_mut(&else_output.references);
|
||||
|
||||
(
|
||||
If {
|
||||
|
@ -1167,7 +1167,7 @@ fn canonicalize_fields<'a>(
|
|||
});
|
||||
}
|
||||
|
||||
output.references = output.references.union(field_out.references);
|
||||
output.references.union_mut(&field_out.references);
|
||||
}
|
||||
Err(CanonicalizeFieldProblem::InvalidOptionalValue {
|
||||
field_name,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::expr::Expr;
|
||||
use crate::pattern::Pattern;
|
||||
use roc_collections::all::ImSet;
|
||||
use roc_collections::all::VecSet;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_types::subs::Variable;
|
||||
|
@ -44,12 +44,12 @@ impl Procedure {
|
|||
/// so it's important that building the same code gives the same order every time!
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct References {
|
||||
pub bound_symbols: ImSet<Symbol>,
|
||||
pub type_lookups: ImSet<Symbol>,
|
||||
pub value_lookups: ImSet<Symbol>,
|
||||
pub bound_symbols: VecSet<Symbol>,
|
||||
pub type_lookups: VecSet<Symbol>,
|
||||
pub value_lookups: VecSet<Symbol>,
|
||||
/// Aliases or opaque types referenced
|
||||
pub referenced_type_defs: ImSet<Symbol>,
|
||||
pub calls: ImSet<Symbol>,
|
||||
pub referenced_type_defs: VecSet<Symbol>,
|
||||
pub calls: VecSet<Symbol>,
|
||||
}
|
||||
|
||||
impl References {
|
||||
|
@ -57,22 +57,15 @@ impl References {
|
|||
Self::default()
|
||||
}
|
||||
|
||||
pub fn union(mut self, other: References) -> Self {
|
||||
self.value_lookups = self.value_lookups.union(other.value_lookups);
|
||||
self.type_lookups = self.type_lookups.union(other.type_lookups);
|
||||
self.calls = self.calls.union(other.calls);
|
||||
self.bound_symbols = self.bound_symbols.union(other.bound_symbols);
|
||||
self.referenced_type_defs = self.referenced_type_defs.union(other.referenced_type_defs);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn union_mut(&mut self, other: References) {
|
||||
self.value_lookups.extend(other.value_lookups);
|
||||
self.type_lookups.extend(other.type_lookups);
|
||||
self.calls.extend(other.calls);
|
||||
self.bound_symbols.extend(other.bound_symbols);
|
||||
self.referenced_type_defs.extend(other.referenced_type_defs);
|
||||
pub fn union_mut(&mut self, other: &References) {
|
||||
self.value_lookups
|
||||
.extend(other.value_lookups.iter().copied());
|
||||
self.type_lookups.extend(other.type_lookups.iter().copied());
|
||||
self.calls.extend(other.calls.iter().copied());
|
||||
self.bound_symbols
|
||||
.extend(other.bound_symbols.iter().copied());
|
||||
self.referenced_type_defs
|
||||
.extend(other.referenced_type_defs.iter().copied());
|
||||
}
|
||||
|
||||
pub fn has_value_lookup(&self, symbol: Symbol) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue