Unify call's fx var with that of the enclosing function

This commit is contained in:
Agus Zubiaga 2024-10-07 21:14:08 -03:00
parent 7871ba182d
commit 5a5abe3bc5
No known key found for this signature in database
23 changed files with 246 additions and 41 deletions

View file

@ -399,7 +399,12 @@ fn find_names_needed(
find_under_alias,
);
}
Error | Structure(EmptyRecord) | Structure(EmptyTagUnion) | ErasedLambda => {
Error
| Structure(EmptyRecord)
| Structure(EmptyTagUnion)
| Pure
| Effectful
| ErasedLambda => {
// Errors and empty records don't need names.
}
}
@ -869,6 +874,12 @@ fn write_content<'a>(
// Easy mode 🤠
buf.push('?');
}
Pure => {
buf.push_str("->");
}
Effectful => {
buf.push_str("=>");
}
RangedNumber(range) => {
buf.push_str("Range(");
for (i, &var) in range.variable_slice().iter().enumerate() {

View file

@ -711,6 +711,8 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
write!(f, ", ^<{ambient_function_var:?}>)")
}
Content::ErasedLambda => write!(f, "ErasedLambda"),
Content::Pure => write!(f, "PureFunction"),
Content::Effectful => write!(f, "EffectfulFunction"),
Content::RangedNumber(range) => {
write!(f, "RangedNumber( {range:?})")
}
@ -1635,6 +1637,8 @@ impl Subs {
);
subs.set_content(Variable::ERASED_LAMBDA, Content::ErasedLambda);
subs.set_content(Variable::PURE, Content::Pure);
subs.set_content(Variable::EFFECTFUL, Content::Effectful);
subs
}
@ -2151,6 +2155,7 @@ impl Subs {
| Content::RangedNumber(_)
| Content::Error => return false,
Content::LambdaSet(_) | Content::ErasedLambda => return false,
Content::Pure | Content::Effectful => return false,
Content::Structure(FlatType::Func(..)) => return true,
Content::Structure(_) => return false,
Content::Alias(_, _, real_var, _) => {
@ -2322,6 +2327,9 @@ pub enum Content {
Alias(Symbol, AliasVariables, Variable, AliasKind),
RangedNumber(crate::num::NumericRange),
Error,
/// The fx type variable for a given function
Pure,
Effectful,
}
/// Stores the lambdas an arrow might pass through; for example
@ -3507,6 +3515,7 @@ fn occurs(
occurs_union(subs, root_var, ctx, safe!(UnionLabels<Symbol>, solved))
}
ErasedLambda => Ok(()),
Pure | Effectful => Ok(()),
RangedNumber(_range_vars) => Ok(()),
})();
@ -3593,7 +3602,9 @@ fn explicit_substitute(
| RigidAbleVar(_, _)
| RecursionVar { .. }
| Error
| ErasedLambda => in_var,
| ErasedLambda
| Pure
| Effectful => in_var,
Structure(flat_type) => {
match flat_type {
@ -3774,7 +3785,9 @@ fn get_var_names(
subs.set_mark(var, Mark::GET_VAR_NAMES);
match desc.content {
Error | FlexVar(None) | FlexAbleVar(None, _) | ErasedLambda => taken_names,
Error | FlexVar(None) | FlexAbleVar(None, _) | ErasedLambda | Pure | Effectful => {
taken_names
}
FlexVar(Some(name_index)) | FlexAbleVar(Some(name_index), _) => add_name(
subs,
@ -4093,6 +4106,11 @@ fn content_to_err_type(
ErrorType::Error
}
Pure | Effectful => {
// Not exposed directly
ErrorType::Error
}
RangedNumber(range) => {
if state.context == ErrorTypeContext::ExpandRanges {
let mut types = Vec::new();
@ -4695,6 +4713,8 @@ impl StorageSubs {
ambient_function: Self::offset_variable(offsets, *ambient_function_var),
}),
ErasedLambda => ErasedLambda,
Pure => Pure,
Effectful => Effectful,
RangedNumber(range) => RangedNumber(*range),
Error => Content::Error,
}
@ -5058,7 +5078,7 @@ fn storage_copy_var_to_help(env: &mut StorageCopyVarToEnv<'_>, var: Variable) ->
copy
}
FlexVar(None) | ErasedLambda | Error => copy,
FlexVar(None) | ErasedLambda | Error | Pure | Effectful => copy,
RecursionVar {
opt_name,
@ -5293,6 +5313,7 @@ fn is_registered(content: &Content) -> bool {
| Content::RigidAbleVar(..) => false,
Content::Structure(FlatType::EmptyRecord | FlatType::EmptyTagUnion) => false,
Content::ErasedLambda => false,
Content::Pure | Content::Effectful => todo!("[purity-inference]"),
Content::Structure(_)
| Content::RecursionVar { .. }
@ -5690,6 +5711,16 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
copy
}
Pure => {
env.target.set(copy, make_descriptor(Pure));
copy
}
Effectful => {
env.target.set(copy, make_descriptor(Effectful));
copy
}
RangedNumber(range) => {
let new_content = RangedNumber(range);
@ -5764,7 +5795,7 @@ fn instantiate_rigids_help(subs: &mut Subs, max_rank: Rank, initial: Variable) {
}
})
}
FlexVar(_) | FlexAbleVar(_, _) | ErasedLambda | Error => (),
FlexVar(_) | FlexAbleVar(_, _) | ErasedLambda | Error | Pure | Effectful => (),
RecursionVar { structure, .. } => {
stack.push(*structure);
@ -5952,7 +5983,9 @@ pub fn get_member_lambda_sets_at_region(subs: &Subs, var: Variable, target_regio
structure: _,
opt_name: _,
}
| Content::ErasedLambda => {}
| Content::ErasedLambda
| Content::Pure
| Content::Effectful => {}
}
}
@ -5978,6 +6011,7 @@ fn is_inhabited(subs: &Subs, var: Variable) -> bool {
// cannot have a tag union without a non-recursive variant.
| Content::RecursionVar { .. } => {}
Content::LambdaSet(_) | Content::ErasedLambda => {}
Content::Pure | Content::Effectful => {}
Content::Structure(structure) => match structure {
FlatType::Apply(_, args) => stack.extend(subs.get_subs_slice(*args)),
FlatType::Func(args, _, ret) => {