mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
switching constraint order fixes things
This commit is contained in:
parent
557c3987e0
commit
2756c9af35
5 changed files with 74 additions and 106 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3776,7 +3776,6 @@ dependencies = [
|
|||
"roc_module",
|
||||
"roc_problem",
|
||||
"roc_region",
|
||||
"roc_solve",
|
||||
"roc_solve_schema",
|
||||
"roc_std",
|
||||
"roc_target",
|
||||
|
|
|
@ -2527,13 +2527,6 @@ pub fn constrain_decls(
|
|||
|
||||
match tag {
|
||||
Value => {
|
||||
constraint = add_host_annotation(
|
||||
types,
|
||||
constraints,
|
||||
declarations.host_exposed_annotations.get(&index),
|
||||
constraint,
|
||||
);
|
||||
|
||||
constraint = constrain_value_def(
|
||||
types,
|
||||
constraints,
|
||||
|
@ -2542,15 +2535,15 @@ pub fn constrain_decls(
|
|||
index,
|
||||
constraint,
|
||||
);
|
||||
}
|
||||
Function(function_def_index) => {
|
||||
|
||||
constraint = add_host_annotation(
|
||||
types,
|
||||
constraints,
|
||||
declarations.host_exposed_annotations.get(&index),
|
||||
constraint,
|
||||
);
|
||||
|
||||
}
|
||||
Function(function_def_index) => {
|
||||
constraint = constrain_function_def(
|
||||
types,
|
||||
constraints,
|
||||
|
@ -2560,6 +2553,13 @@ pub fn constrain_decls(
|
|||
function_def_index,
|
||||
constraint,
|
||||
);
|
||||
|
||||
constraint = add_host_annotation(
|
||||
types,
|
||||
constraints,
|
||||
declarations.host_exposed_annotations.get(&index),
|
||||
constraint,
|
||||
);
|
||||
}
|
||||
Recursive(_) | TailRecursive(_) => {
|
||||
constraint = add_host_annotation(
|
||||
|
|
|
@ -5649,8 +5649,6 @@ fn build_pending_specializations<'a>(
|
|||
|
||||
let is_host_exposed = exposed_to_host.top_level_values.contains_key(&symbol);
|
||||
|
||||
// TODO remove clones (with drain)
|
||||
let annotation = declarations.annotations[index].clone();
|
||||
let body = declarations.expressions[index].clone();
|
||||
|
||||
let tag = declarations.declarations[index];
|
||||
|
|
|
@ -24,7 +24,6 @@ roc_std = { path = "../../roc_std" }
|
|||
roc_target = { path = "../roc_target" }
|
||||
roc_tracing = { path = "../../tracing" }
|
||||
roc_types = { path = "../types" }
|
||||
roc_solve = { path = "../solve" }
|
||||
roc_solve_schema = { path = "../solve_schema" }
|
||||
roc_unify = { path = "../unify" }
|
||||
ven_pretty = { path = "../../vendor/pretty" }
|
||||
|
|
|
@ -11,8 +11,7 @@ use crate::layout::{
|
|||
};
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use bumpalo::Bump;
|
||||
use roc_can::abilities::{AbilitiesStore, SpecializationId};
|
||||
use roc_can::constraint::Constraints;
|
||||
use roc_can::abilities::SpecializationId;
|
||||
use roc_can::expr::{AnnotatedMark, ClosureData, ExpectLookup};
|
||||
use roc_can::module::ExposedByModule;
|
||||
use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, MutMap};
|
||||
|
@ -32,15 +31,12 @@ use roc_module::low_level::{LowLevel, LowLevelWrapperType};
|
|||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
use roc_problem::can::{RuntimeError, ShadowKind};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_solve::ability::ObligationCache;
|
||||
use roc_solve::{Aliases, DerivedEnv, InferenceEnv, Pools};
|
||||
use roc_std::RocDec;
|
||||
use roc_target::TargetInfo;
|
||||
use roc_types::subs::{
|
||||
instantiate_rigids, storage_copy_var_to, Content, ExhaustiveMark, FlatType, Rank,
|
||||
RedundantMark, StorageSubs, Subs, SubsFmtContent, Variable, VariableSubsSlice,
|
||||
instantiate_rigids, storage_copy_var_to, Content, ExhaustiveMark, FlatType,
|
||||
RedundantMark, StorageSubs, Subs, Variable, VariableSubsSlice,
|
||||
};
|
||||
use roc_types::types::Types;
|
||||
use std::collections::HashMap;
|
||||
use ven_pretty::{text, BoxAllocator, DocAllocator, DocBuilder};
|
||||
|
||||
|
@ -753,32 +749,43 @@ impl<'a> Specialized<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn insert_specialized(&mut self, symbol: Symbol, layout: ProcLayout<'a>, proc: Proc<'a>) {
|
||||
fn insert_specialized(
|
||||
&mut self,
|
||||
symbol: Symbol,
|
||||
layout: ProcLayout<'a>,
|
||||
proc: Proc<'a>,
|
||||
) -> SpecializedIndex {
|
||||
for (i, s) in self.symbols.iter().enumerate() {
|
||||
if *s == symbol && self.proc_layouts[i] == layout {
|
||||
match &self.procedures[i] {
|
||||
InProgressProc::InProgress => {
|
||||
self.procedures[i] = InProgressProc::Done(proc);
|
||||
return;
|
||||
return SpecializedIndex(i);
|
||||
}
|
||||
InProgressProc::Done(_) => {
|
||||
// overwrite existing! this is important in practice
|
||||
// TODO investigate why we generate the wrong proc in some cases and then
|
||||
// correct later
|
||||
self.procedures[i] = InProgressProc::Done(proc);
|
||||
return;
|
||||
return SpecializedIndex(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the key/layout combo was not found; insert it
|
||||
let i = self.symbols.len();
|
||||
|
||||
self.symbols.push(symbol);
|
||||
self.proc_layouts.push(layout);
|
||||
self.procedures.push(InProgressProc::Done(proc));
|
||||
|
||||
SpecializedIndex(i)
|
||||
}
|
||||
}
|
||||
|
||||
struct SpecializedIndex(usize);
|
||||
|
||||
/// Uniquely determines the specialization of a polymorphic (non-proc) value symbol.
|
||||
/// Two specializations are equivalent if their [`SpecializationMark`]s are equal.
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
|
@ -3069,33 +3076,16 @@ fn specialize_host_specializations<'a>(
|
|||
|
||||
let offset_variable = StorageSubs::merge_into(store, env.subs);
|
||||
|
||||
for (symbol, ls_from_app, from_platform) in it {
|
||||
dbg!(symbol);
|
||||
specialize_external_help(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
symbol,
|
||||
offset_variable(ls_from_app),
|
||||
);
|
||||
|
||||
let from_app = offset_variable(ls_from_app);
|
||||
for (symbol, from_app, from_platform) in it {
|
||||
let from_app = offset_variable(from_app);
|
||||
let index = specialize_external_help(env, procs, layout_cache, symbol, from_app);
|
||||
|
||||
// now run the lambda set numbering scheme
|
||||
let mut layout_env =
|
||||
layout::Env::from_components(layout_cache, env.subs, env.arena, env.target_info);
|
||||
let hels = find_lambda_sets(&mut layout_env, from_platform);
|
||||
|
||||
dbg!(&hels);
|
||||
|
||||
// now unify
|
||||
|
||||
let content = env.subs.get_without_compacting(from_app).content;
|
||||
dbg!(SubsFmtContent(&content, env.subs,));
|
||||
|
||||
let content = env.subs.get_without_compacting(from_platform).content;
|
||||
dbg!(SubsFmtContent(&content, env.subs,));
|
||||
|
||||
let mut unify_env = roc_unify::Env::new(
|
||||
env.subs,
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -3119,10 +3109,45 @@ fn specialize_host_specializations<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
for (id, unified_variable, _) in hels {
|
||||
let content = env.subs.get_without_compacting(unified_variable).content;
|
||||
let mut aliases = BumpMap::default();
|
||||
|
||||
dbg!(SubsFmtContent(&content, env.subs,));
|
||||
for (id, _, raw_function_layout) in hels {
|
||||
let symbol = env.unique_symbol();
|
||||
let lambda_name = LambdaName::no_niche(symbol);
|
||||
|
||||
let (key, (top_level, proc)) = generate_host_exposed_function(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
lambda_name,
|
||||
raw_function_layout,
|
||||
);
|
||||
|
||||
procs
|
||||
.specialized
|
||||
.insert_specialized(symbol, top_level, proc);
|
||||
|
||||
let hels = HostExposedLambdaSet {
|
||||
id,
|
||||
symbol,
|
||||
proc_layout: top_level,
|
||||
raw_function_layout,
|
||||
};
|
||||
|
||||
aliases.insert(key, hels);
|
||||
}
|
||||
|
||||
let in_progress = &mut procs.specialized.procedures[index.0];
|
||||
let InProgressProc::Done(proc) = in_progress else { unreachable!() };
|
||||
|
||||
match &mut proc.host_exposed_layouts {
|
||||
HostExposedLayouts::HostExposed { aliases: old, .. } => old.extend(aliases),
|
||||
hep @ HostExposedLayouts::NotHostExposed => {
|
||||
*hep = HostExposedLayouts::HostExposed {
|
||||
aliases,
|
||||
rigids: Default::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3148,7 +3173,7 @@ fn specialize_external_specializations<'a>(
|
|||
// duplicate specializations, and the insertion into a hash map
|
||||
// below will deduplicate them.
|
||||
|
||||
specialize_external_help(env, procs, layout_cache, symbol, imported_variable)
|
||||
specialize_external_help(env, procs, layout_cache, symbol, imported_variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3159,7 +3184,7 @@ fn specialize_external_help<'a>(
|
|||
layout_cache: &mut LayoutCache<'a>,
|
||||
name: LambdaName<'a>,
|
||||
variable: Variable,
|
||||
) {
|
||||
) -> SpecializedIndex {
|
||||
let partial_proc_id = match procs.partial_procs.symbol_to_id(name.name()) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
|
@ -3171,7 +3196,7 @@ fn specialize_external_help<'a>(
|
|||
specialize_variable(env, procs, name, layout_cache, variable, partial_proc_id);
|
||||
|
||||
match specialization_result {
|
||||
Ok((mut proc, layout)) => {
|
||||
Ok((proc, layout)) => {
|
||||
let top_level = ProcLayout::from_raw_named(env.arena, name, layout);
|
||||
|
||||
if procs.is_module_thunk(name.name()) {
|
||||
|
@ -3218,64 +3243,11 @@ fn specialize_external_help<'a>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, let's generate the host-exposed lambda set wrappers from the type of the
|
||||
// host-exported function.
|
||||
{
|
||||
let extern_names = {
|
||||
let mut layout_env = layout::Env::from_components(
|
||||
layout_cache,
|
||||
env.subs,
|
||||
env.arena,
|
||||
env.target_info,
|
||||
);
|
||||
|
||||
find_lambda_sets(&mut layout_env, variable)
|
||||
};
|
||||
|
||||
let mut aliases = BumpMap::default();
|
||||
|
||||
for (id, _, raw_function_layout) in extern_names {
|
||||
let symbol = env.unique_symbol();
|
||||
let lambda_name = LambdaName::no_niche(symbol);
|
||||
|
||||
let (key, (top_level, proc)) = generate_host_exposed_function(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
lambda_name,
|
||||
raw_function_layout,
|
||||
);
|
||||
|
||||
procs
|
||||
.specialized
|
||||
.insert_specialized(symbol, top_level, proc);
|
||||
|
||||
let hels = HostExposedLambdaSet {
|
||||
id,
|
||||
symbol,
|
||||
proc_layout: top_level,
|
||||
raw_function_layout,
|
||||
};
|
||||
|
||||
aliases.insert(key, hels);
|
||||
}
|
||||
|
||||
match &mut proc.host_exposed_layouts {
|
||||
HostExposedLayouts::HostExposed { aliases: old, .. } => old.extend(aliases),
|
||||
hep @ HostExposedLayouts::NotHostExposed => {
|
||||
*hep = HostExposedLayouts::HostExposed {
|
||||
aliases,
|
||||
rigids: Default::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
procs
|
||||
.specialized
|
||||
.insert_specialized(name.name(), top_level, proc);
|
||||
.insert_specialized(name.name(), top_level, proc)
|
||||
}
|
||||
Err(SpecializeFailure { attempted_layout }) => {
|
||||
let proc = generate_runtime_error_function(env, name, attempted_layout);
|
||||
|
@ -3284,7 +3256,7 @@ fn specialize_external_help<'a>(
|
|||
|
||||
procs
|
||||
.specialized
|
||||
.insert_specialized(name.name(), top_level, proc);
|
||||
.insert_specialized(name.name(), top_level, proc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5359,7 +5331,7 @@ pub fn with_hole<'a>(
|
|||
if let Err(e) = inserted {
|
||||
return runtime_error(
|
||||
env,
|
||||
env.arena.alloc(format!("RuntimeError: {:?}", e,)),
|
||||
env.arena.alloc(format!("RuntimeError: {e:?}")),
|
||||
);
|
||||
}
|
||||
drop(inserted);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue