Merge remote-tracking branch 'origin/main' into abilities-syntax

This commit is contained in:
Richard Feldman 2023-08-10 20:29:27 -04:00
commit 2da41be29f
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
524 changed files with 47536 additions and 15089 deletions

View file

@ -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"

View 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);
});
}
}

View file

@ -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

View file

@ -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