mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge remote-tracking branch 'origin/main' into abilities-syntax
This commit is contained in:
commit
2da41be29f
524 changed files with 47536 additions and 15089 deletions
|
@ -8,7 +8,6 @@ license.workspace = true
|
|||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
|
||||
[dependencies.roc_collections]
|
||||
path = "../collections"
|
||||
|
@ -27,3 +26,9 @@ path = "../debug_flags"
|
|||
|
||||
[dependencies.roc_tracing]
|
||||
path = "../../tracing"
|
||||
|
||||
[dependencies.roc_checkmate]
|
||||
path = "../checkmate"
|
||||
|
||||
[dependencies.roc_solve_schema]
|
||||
path = "../solve_schema"
|
||||
|
|
132
crates/compiler/unify/src/env.rs
Normal file
132
crates/compiler/unify/src/env.rs
Normal file
|
@ -0,0 +1,132 @@
|
|||
#[cfg(debug_assertions)]
|
||||
use roc_checkmate::debug_checkmate;
|
||||
use roc_collections::VecSet;
|
||||
use roc_types::subs::{Descriptor, Subs, Variable};
|
||||
|
||||
pub struct Env<'a> {
|
||||
subs: &'a mut Subs,
|
||||
#[cfg(debug_assertions)]
|
||||
cm: Option<&'a mut roc_checkmate::Collector>,
|
||||
seen_recursion: VecSet<(Variable, Variable)>,
|
||||
fixed_variables: VecSet<Variable>,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Env<'_> {
|
||||
type Target = Subs;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.subs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for Env<'_> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.subs
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Env<'a> {
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn new(subs: &'a mut Subs, cm: Option<&'a mut roc_checkmate::Collector>) -> Self {
|
||||
Self {
|
||||
subs,
|
||||
cm,
|
||||
seen_recursion: Default::default(),
|
||||
fixed_variables: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub fn new(subs: &'a mut Subs) -> Self {
|
||||
Self {
|
||||
subs,
|
||||
seen_recursion: Default::default(),
|
||||
fixed_variables: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add_recursion_pair(&mut self, var1: Variable, var2: Variable) {
|
||||
let pair = (
|
||||
self.subs.get_root_key_without_compacting(var1),
|
||||
self.subs.get_root_key_without_compacting(var2),
|
||||
);
|
||||
|
||||
let already_seen = self.seen_recursion.insert(pair);
|
||||
debug_assert!(!already_seen);
|
||||
}
|
||||
|
||||
pub(crate) fn remove_recursion_pair(&mut self, var1: Variable, var2: Variable) {
|
||||
#[cfg(debug_assertions)]
|
||||
let size_before = self.seen_recursion.len();
|
||||
|
||||
self.seen_recursion.retain(|(v1, v2)| {
|
||||
let is_recursion_pair = self.subs.equivalent_without_compacting(*v1, var1)
|
||||
&& self.subs.equivalent_without_compacting(*v2, var2);
|
||||
!is_recursion_pair
|
||||
});
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
let size_after = self.seen_recursion.len();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
debug_assert!(size_after < size_before, "nothing was removed");
|
||||
}
|
||||
|
||||
pub(crate) fn seen_recursion_pair(&self, var1: Variable, var2: Variable) -> bool {
|
||||
let (var1, var2) = (
|
||||
self.subs.get_root_key_without_compacting(var1),
|
||||
self.subs.get_root_key_without_compacting(var2),
|
||||
);
|
||||
|
||||
self.seen_recursion.contains(&(var1, var2))
|
||||
}
|
||||
|
||||
pub(crate) fn was_fixed(&self, var: Variable) -> bool {
|
||||
self.fixed_variables
|
||||
.iter()
|
||||
.any(|fixed_var| self.subs.equivalent_without_compacting(*fixed_var, var))
|
||||
}
|
||||
|
||||
pub(crate) fn extend_fixed_variables(&mut self, vars: impl IntoIterator<Item = Variable>) {
|
||||
self.fixed_variables.extend(vars);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub(crate) fn union(&mut self, left: Variable, right: Variable, desc: Descriptor) {
|
||||
let left_root = self.subs.get_root_key_without_compacting(left);
|
||||
let right_root = self.subs.get_root_key_without_compacting(right);
|
||||
|
||||
self.subs.union(left, right, desc);
|
||||
|
||||
debug_checkmate!(self.cm, cm => {
|
||||
let new_root = self.subs.get_root_key_without_compacting(left);
|
||||
cm.set_descriptor(self.subs, new_root, desc);
|
||||
cm.unify(self.subs, left_root, new_root);
|
||||
cm.unify(self.subs, right_root, new_root);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub(crate) fn union(&mut self, left: Variable, right: Variable, desc: Descriptor) {
|
||||
self.subs.union(left, right, desc);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub(crate) fn debug_start_unification(
|
||||
&mut self,
|
||||
left: Variable,
|
||||
right: Variable,
|
||||
mode: roc_solve_schema::UnificationMode,
|
||||
) {
|
||||
debug_checkmate!(self.cm, cm => {
|
||||
cm.start_unification(self.subs, left, right, mode);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub(crate) fn debug_end_unification(&mut self, left: Variable, right: Variable, success: bool) {
|
||||
debug_checkmate!(self.cm, cm => {
|
||||
cm.end_unification(self.subs, left, right, success);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
//! Fix fixpoints of recursive types.
|
||||
|
||||
use roc_debug_flags::dbg_do;
|
||||
#[cfg(debug_assertions)]
|
||||
use roc_debug_flags::ROC_PRINT_FIXPOINT_FIXING;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||
|
||||
|
@ -80,6 +83,19 @@ struct Update {
|
|||
/// to decide it.
|
||||
#[must_use]
|
||||
pub fn fix_fixpoint(subs: &mut Subs, left: Variable, right: Variable) -> Vec<Variable> {
|
||||
dbg_do!(ROC_PRINT_FIXPOINT_FIXING, {
|
||||
eprintln!("🛠️🛠️🛠️🛠️🛠️🛠️🛠️🛠️ BEGIN FIXPOINT FIXING 🛠️🛠️🛠️🛠️🛠️🛠️🛠️🛠️");
|
||||
eprintln!(
|
||||
"🛠️🛠️ ({:?}-{:?}): {:?} {:?} 🛠️ {:?} {:?}",
|
||||
subs.get_root_key_without_compacting(left),
|
||||
subs.get_root_key_without_compacting(right),
|
||||
left,
|
||||
subs.dbg(left),
|
||||
right,
|
||||
subs.dbg(right),
|
||||
);
|
||||
});
|
||||
|
||||
let updates = find_chain(subs, left, right);
|
||||
let mut new = vec![];
|
||||
|
||||
|
@ -93,6 +109,10 @@ pub fn fix_fixpoint(subs: &mut Subs, left: Variable, right: Variable) -> Vec<Var
|
|||
new.push(source_of_truth);
|
||||
}
|
||||
|
||||
dbg_do!(ROC_PRINT_FIXPOINT_FIXING, {
|
||||
eprintln!("🛠️🛠️🛠️🛠️🛠️🛠️🛠️🛠️ END FIXPOINT FIXING 🛠️🛠️🛠️🛠️🛠️🛠️🛠️🛠️");
|
||||
});
|
||||
|
||||
new
|
||||
}
|
||||
|
||||
|
@ -164,6 +184,16 @@ fn find_chain(subs: &Subs, left: Variable, right: Variable) -> impl Iterator<Ite
|
|||
let left = subs.get_root_key_without_compacting(left);
|
||||
let right = subs.get_root_key_without_compacting(right);
|
||||
|
||||
dbg_do!(ROC_PRINT_FIXPOINT_FIXING, {
|
||||
eprintln!(
|
||||
"❓ ({:?}-{:?}): {:?} 🔗 {:?}",
|
||||
left,
|
||||
right,
|
||||
subs.dbg(left),
|
||||
subs.dbg(right),
|
||||
);
|
||||
});
|
||||
|
||||
if (left, right) == needle {
|
||||
return Ok(vec![needle]);
|
||||
}
|
||||
|
@ -180,7 +210,19 @@ fn find_chain(subs: &Subs, left: Variable, right: Variable) -> impl Iterator<Ite
|
|||
| (FlexAbleVar(..), FlexAbleVar(..))
|
||||
| (Error, Error)
|
||||
| (RangedNumber(..), RangedNumber(..)) => Err(()),
|
||||
(RecursionVar { .. }, RecursionVar { .. }) => internal_error!("not expected"),
|
||||
(RecursionVar { structure: left_rec, .. }, RecursionVar { structure: right_rec, .. }) => {
|
||||
// This might be a case like fix-point fixing
|
||||
//
|
||||
// [ Bar [ Bar <a>, Foo ], Foo ] as <a> 🛠️ [ Bar <b>, Foo ] as <b>
|
||||
//
|
||||
// where we hit a comparison between <a> and <b>. In this case, follow each
|
||||
// recursion point independently and see if we can find the chain to the needle
|
||||
// we were searching for.
|
||||
let search_deeper_left = |_| help(subs, needle, *left_rec, right);
|
||||
let search_deeper_right = |_| help(subs, needle, left, *right_rec);
|
||||
let chain = search_deeper_left(()).or_else(search_deeper_right)?;
|
||||
Ok(chain)
|
||||
}
|
||||
(RecursionVar { structure, .. }, _) => {
|
||||
// By construction, the recursion variables will be adjusted to be equal after
|
||||
// the transformation, so we can immediately look at the inner variable. We only
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
// See github.com/roc-lang/roc/issues/800 for discussion of the large_enum_variant check.
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
|
||||
mod env;
|
||||
mod fix;
|
||||
pub mod unify;
|
||||
pub use env::Env;
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue