Remove unspecialized following unification links

This commit is contained in:
Ayaz Hafiz 2022-06-03 15:02:09 -05:00
parent b2fe2ec8f0
commit 0476d4a65c
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
5 changed files with 57 additions and 31 deletions

View file

@ -1735,14 +1735,12 @@ fn find_specializaton_lambda_sets(
uls_before.into_iter().chain(uls_after.into_iter()).copied(), uls_before.into_iter().chain(uls_after.into_iter()).copied(),
); );
subs.set_content( let new_lambda_set_content = Content::LambdaSet(LambdaSet {
lambda_set,
Content::LambdaSet(LambdaSet {
solved, solved,
recursion_var, recursion_var,
unspecialized: new_unspecialized, unspecialized: new_unspecialized,
}), });
); subs.set_content(lambda_set, new_lambda_set_content);
let old_specialized = let old_specialized =
specialization_lambda_sets.insert(specialized_lset_region, lambda_set); specialization_lambda_sets.insert(specialized_lset_region, lambda_set);
@ -1812,6 +1810,7 @@ fn compact_lambda_set(
// //
// {a, b} = default {} // {a, b} = default {}
// # ^^^^^^^ {} -[{a: t1, b: t2}:default:1] // # ^^^^^^^ {} -[{a: t1, b: t2}:default:1]
new_unspecialized.push(uls);
continue; continue;
} }
Alias(opaque, _, _, AliasKind::Opaque) => opaque, Alias(opaque, _, _, AliasKind::Opaque) => opaque,

View file

@ -277,7 +277,7 @@ mod solve_expr {
let var = find_type_at(region, &decls) let var = find_type_at(region, &decls)
.unwrap_or_else(|| panic!("No type for {} ({:?})!", &text, region)); .unwrap_or_else(|| panic!("No type for {} ({:?})!", &text, region));
let actual_str = name_and_print_var(var, subs, home, &interns, PrintLambdaSets::No); let actual_str = name_and_print_var(var, subs, home, &interns, PrintLambdaSets::Yes);
let elaborated = match find_ability_member_at(region, &decls) { let elaborated = match find_ability_member_at(region, &decls) {
Some((member, specialization_id)) => { Some((member, specialization_id)) => {
@ -6318,8 +6318,8 @@ mod solve_expr {
"# "#
), ),
&[ &[
"u8 : U8 -> Encoder Linear", "u8 : U8 -[[u8(22)]]-> Encoder Linear",
"toEncoder : MyU8 -> Encoder fmt | fmt has Format", "toEncoder : MyU8 -[[toEncoder(23)]]-> Encoder fmt | fmt has Format",
"myU8Bytes : List U8", "myU8Bytes : List U8",
], ],
) )
@ -6426,7 +6426,7 @@ mod solve_expr {
a a
"# "#
), ),
&["A#default : {} -> A"], &["A#default : {} -[[default(5)]]-> A"],
) )
} }
@ -6469,7 +6469,9 @@ mod solve_expr {
# ^^^^^^^^^ # ^^^^^^^^^
"# "#
), ),
&["Encoding#toEncoder : { a : Str } -> Encoder fmt | fmt has EncoderFormatting"], &[
"Encoding#toEncoder : { a : Str } -[[] + { a : Str }:toEncoder(2):1]-> Encoder fmt | fmt has EncoderFormatting",
],
) )
} }
@ -6489,7 +6491,7 @@ mod solve_expr {
# ^^^^^^^^^ # ^^^^^^^^^
"# "#
), ),
&["Encoding#toEncoder : { a : A } -> Encoder fmt | fmt has EncoderFormatting"], &["Encoding#toEncoder : { a : A } -[[] + { a : A }:toEncoder(2):1]-> Encoder fmt | fmt has EncoderFormatting"],
) )
} }
} }

View file

@ -585,13 +585,21 @@ fn write_content<'a>(
}) => { }) => {
buf.push_str("[["); buf.push_str("[[");
let print_symbol = |symbol: &Symbol| {
format!(
"{}({})",
symbol.as_str(&env.interns),
symbol.ident_id().index(),
)
};
write_sorted_tags2( write_sorted_tags2(
env, env,
ctx, ctx,
subs, subs,
buf, buf,
solved.unsorted_lambdas(subs), solved.unsorted_lambdas(subs),
|symbol| symbol.as_str(&env.interns), print_symbol,
); );
buf.push(']'); buf.push(']');
@ -619,7 +627,7 @@ fn write_content<'a>(
Parens::Unnecessary, Parens::Unnecessary,
); );
buf.push(':'); buf.push(':');
buf.push_str(member.as_str(&env.interns)); buf.push_str(&print_symbol(member));
buf.push(':'); buf.push(':');
buf.push_str(&region.to_string()); buf.push_str(&region.to_string());
} }
@ -743,13 +751,13 @@ fn write_ext_content<'a>(
} }
} }
fn write_sorted_tags2<'a, 'b, L: 'b>( fn write_sorted_tags2<'a, L>(
env: &'b Env, env: &Env,
ctx: &mut Context<'a>, ctx: &mut Context<'a>,
subs: &'a Subs, subs: &'a Subs,
buf: &mut String, buf: &mut String,
tags: UnsortedUnionLabels<'b, L>, tags: UnsortedUnionLabels<L>,
label_to_string: impl Fn(&'b L) -> &'b str, label_to_string: impl Fn(&L) -> String,
) where ) where
L: Label + Ord, L: Label + Ord,
{ {
@ -766,7 +774,7 @@ fn write_sorted_tags2<'a, 'b, L: 'b>(
any_written_yet = true; any_written_yet = true;
} }
buf.push_str(label_to_string(label)); buf.push_str(&label_to_string(label));
for var in vars { for var in vars {
buf.push(' '); buf.push(' ');
@ -935,7 +943,7 @@ fn write_flat_type<'a>(
// Sort the fields so they always end up in the same order. // Sort the fields so they always end up in the same order.
let (tags, new_ext_var) = tags.unsorted_tags_and_ext(subs, *ext_var); let (tags, new_ext_var) = tags.unsorted_tags_and_ext(subs, *ext_var);
write_sorted_tags2(env, ctx, subs, buf, tags, |tag| tag.0.as_str()); write_sorted_tags2(env, ctx, subs, buf, tags, |tag| tag.0.as_str().to_string());
buf.push(']'); buf.push(']');
@ -965,7 +973,7 @@ fn write_flat_type<'a>(
buf.push('['); buf.push('[');
let (tags, new_ext_var) = tags.unsorted_tags_and_ext(subs, *ext_var); let (tags, new_ext_var) = tags.unsorted_tags_and_ext(subs, *ext_var);
write_sorted_tags2(env, ctx, subs, buf, tags, |tag| tag.0.as_str()); write_sorted_tags2(env, ctx, subs, buf, tags, |tag| tag.0.as_str().to_string());
buf.push(']'); buf.push(']');

View file

@ -315,7 +315,8 @@ pub struct UlsOfVar(VecMap<Variable, VecSet<Variable>>);
impl UlsOfVar { impl UlsOfVar {
pub fn add(&mut self, var: Variable, dependent_lambda_set: Variable) -> bool { pub fn add(&mut self, var: Variable, dependent_lambda_set: Variable) -> bool {
// TODO: should we be checking root key here? // NOTE: this adds the var directly without following unification links.
// [Subs::remove_dependent_unspecialized_lambda_sets] follows unifications when removing.
let set = self.0.get_or_insert(var, Default::default); let set = self.0.get_or_insert(var, Default::default);
set.insert(dependent_lambda_set) set.insert(dependent_lambda_set)
} }
@ -325,7 +326,8 @@ impl UlsOfVar {
var: Variable, var: Variable,
dependent_lambda_sets: impl IntoIterator<Item = Variable>, dependent_lambda_sets: impl IntoIterator<Item = Variable>,
) { ) {
// TODO: should we be checking root key here? // NOTE: this adds the var directly without following unification links.
// [Subs::remove_dependent_unspecialized_lambda_sets] follows unifications when removing.
let set = self.0.get_or_insert(var, Default::default); let set = self.0.get_or_insert(var, Default::default);
set.extend(dependent_lambda_sets); set.extend(dependent_lambda_sets);
} }
@ -344,6 +346,7 @@ impl UlsOfVar {
self.0.remove(&var).map(|(_, v)| v) self.0.remove(&var).map(|(_, v)| v)
} }
/// NOTE: this does not follow unification links.
pub fn drain(self) -> impl Iterator<Item = (Variable, impl Iterator<Item = Variable>)> { pub fn drain(self) -> impl Iterator<Item = (Variable, impl Iterator<Item = Variable>)> {
self.0 self.0
.into_iter() .into_iter()
@ -1991,6 +1994,21 @@ impl Subs {
_ => internal_error!("not a lambda set"), _ => internal_error!("not a lambda set"),
} }
} }
pub fn remove_dependent_unspecialized_lambda_sets(
&mut self,
var: Variable,
) -> impl Iterator<Item = Variable> + '_ {
let utable = &self.utable;
let root_var = utable.root_key_without_compacting(var);
self.uls_of_var
.0
.drain_filter(move |cand_var, _| {
utable.root_key_without_compacting(*cand_var) == root_var
})
.flat_map(|(_, lambda_set_vars)| lambda_set_vars.into_iter())
}
} }
#[inline(always)] #[inline(always)]

View file

@ -2162,11 +2162,10 @@ fn merge_flex_able_with_concrete(
// //
// If we ever organize ability implementations so that they are well-known before any other // If we ever organize ability implementations so that they are well-known before any other
// unification is done, they can be solved in-band here! // unification is done, they can be solved in-band here!
if let Some(uls_of_concrete) = subs.uls_of_var.remove_dependents(flex_able_var) { let uls_of_concrete = subs.remove_dependent_unspecialized_lambda_sets(flex_able_var);
outcome outcome
.lambda_sets_to_specialize .lambda_sets_to_specialize
.extend(flex_able_var, uls_of_concrete); .extend(flex_able_var, uls_of_concrete);
}
outcome outcome
} }