mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Internal error when late compaction fails
This commit is contained in:
parent
f4fc9cbe04
commit
266f56d25b
2 changed files with 37 additions and 6 deletions
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_can::abilities::AbilitiesStore;
|
use roc_can::abilities::AbilitiesStore;
|
||||||
use roc_solve::solve::{compact_lambda_sets_of_vars, Pools};
|
use roc_solve::solve::{compact_lambda_sets_of_vars, Phase, Pools};
|
||||||
use roc_types::subs::{Subs, Variable};
|
use roc_types::subs::{Subs, Variable};
|
||||||
use roc_unify::unify::{unify as unify_unify, Mode, Unified};
|
use roc_unify::unify::{unify as unify_unify, Mode, Unified};
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ pub fn unify(
|
||||||
&mut pools,
|
&mut pools,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
lambda_sets_to_specialize,
|
lambda_sets_to_specialize,
|
||||||
|
Phase::Late,
|
||||||
);
|
);
|
||||||
// Pools are only used to keep track of variable ranks for generalization purposes.
|
// Pools are only used to keep track of variable ranks for generalization purposes.
|
||||||
// Since we break generalization during monomorphization, `pools` is irrelevant
|
// Since we break generalization during monomorphization, `pools` is irrelevant
|
||||||
|
|
|
@ -81,6 +81,18 @@ use roc_unify::unify::{unify, Mode, Obligated, Unified::*};
|
||||||
// Ranks are used to limit the number of type variables considered for generalization. Only those inside
|
// Ranks are used to limit the number of type variables considered for generalization. Only those inside
|
||||||
// of the let (so those used in inferring the type of `\x -> x`) are considered.
|
// of the let (so those used in inferring the type of `\x -> x`) are considered.
|
||||||
|
|
||||||
|
/// What phase in the compiler is reaching out to solve types.
|
||||||
|
/// This is important to distinguish subtle differences in the behavior of the solving algorithm.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Phase {
|
||||||
|
/// The regular type-solving phase.
|
||||||
|
/// Here we can assume that some information is still unknown, and react to that.
|
||||||
|
Solve,
|
||||||
|
/// Calls into solve during later phases of compilation, namely monomorphization.
|
||||||
|
/// Here we expect all information is known.
|
||||||
|
Late,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TypeError {
|
pub enum TypeError {
|
||||||
BadExpr(Region, Category, ErrorType, Expected<ErrorType>),
|
BadExpr(Region, Category, ErrorType, Expected<ErrorType>),
|
||||||
|
@ -563,6 +575,7 @@ fn run_in_place(
|
||||||
&mut pools,
|
&mut pools,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
deferred_uls_to_resolve,
|
deferred_uls_to_resolve,
|
||||||
|
Phase::Solve,
|
||||||
);
|
);
|
||||||
|
|
||||||
state.env
|
state.env
|
||||||
|
@ -1771,6 +1784,7 @@ pub fn compact_lambda_sets_of_vars(
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
abilities_store: &AbilitiesStore,
|
abilities_store: &AbilitiesStore,
|
||||||
uls_of_var: UlsOfVar,
|
uls_of_var: UlsOfVar,
|
||||||
|
phase: Phase,
|
||||||
) {
|
) {
|
||||||
let mut seen = VecSet::default();
|
let mut seen = VecSet::default();
|
||||||
for (_, lambda_sets) in uls_of_var.drain() {
|
for (_, lambda_sets) in uls_of_var.drain() {
|
||||||
|
@ -1780,7 +1794,7 @@ pub fn compact_lambda_sets_of_vars(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
compact_lambda_set(subs, arena, pools, abilities_store, root_lset);
|
compact_lambda_set(subs, arena, pools, abilities_store, root_lset, phase);
|
||||||
seen.insert(root_lset);
|
seen.insert(root_lset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1792,6 +1806,7 @@ fn compact_lambda_set(
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
abilities_store: &AbilitiesStore,
|
abilities_store: &AbilitiesStore,
|
||||||
this_lambda_set: Variable,
|
this_lambda_set: Variable,
|
||||||
|
phase: Phase,
|
||||||
) {
|
) {
|
||||||
let LambdaSet {
|
let LambdaSet {
|
||||||
solved,
|
solved,
|
||||||
|
@ -1842,12 +1857,20 @@ fn compact_lambda_set(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let specialized_lambda_set = match abilities_store.get_specialization(member, *opaque) {
|
let opt_specialization = abilities_store.get_specialization(member, *opaque);
|
||||||
None => {
|
let specialized_lambda_set = match (phase, opt_specialization) {
|
||||||
|
(Phase::Solve, None) => {
|
||||||
// doesn't specialize, we'll have reported an error for this
|
// doesn't specialize, we'll have reported an error for this
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Some(specialization) => *specialization
|
(Phase::Late, None) => {
|
||||||
|
internal_error!(
|
||||||
|
"expected to know a specialization for {:?}#{:?}, but it wasn't found",
|
||||||
|
opaque,
|
||||||
|
member
|
||||||
|
);
|
||||||
|
}
|
||||||
|
(_, Some(specialization)) => *specialization
|
||||||
.specialization_lambda_sets
|
.specialization_lambda_sets
|
||||||
.get(®ion)
|
.get(®ion)
|
||||||
.expect("lambda set region not resolved"),
|
.expect("lambda set region not resolved"),
|
||||||
|
@ -1855,7 +1878,14 @@ fn compact_lambda_set(
|
||||||
|
|
||||||
// Ensure the specialization lambda set is already compacted.
|
// Ensure the specialization lambda set is already compacted.
|
||||||
if subs.get_root_key(specialized_lambda_set) != subs.get_root_key(this_lambda_set) {
|
if subs.get_root_key(specialized_lambda_set) != subs.get_root_key(this_lambda_set) {
|
||||||
compact_lambda_set(subs, arena, pools, abilities_store, specialized_lambda_set);
|
compact_lambda_set(
|
||||||
|
subs,
|
||||||
|
arena,
|
||||||
|
pools,
|
||||||
|
abilities_store,
|
||||||
|
specialized_lambda_set,
|
||||||
|
phase,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the specialization lambda set we'll unify with is not a generalized one, but one
|
// Ensure the specialization lambda set we'll unify with is not a generalized one, but one
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue