mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Support OIOP for type aliases
This commit is contained in:
parent
6ee2fb496d
commit
debe6332c5
21 changed files with 452 additions and 115 deletions
|
@ -802,12 +802,12 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
|
|||
};
|
||||
write!(f, "Flex({})", name)
|
||||
}
|
||||
Content::FlexAbleVar(name, symbol) => {
|
||||
Content::FlexAbleVar(name, symbols) => {
|
||||
let name = match name {
|
||||
Some(index) => subs[*index].as_str(),
|
||||
None => "_",
|
||||
};
|
||||
write!(f, "FlexAble({}, {:?})", name, symbol)
|
||||
write!(f, "FlexAble({}, {:?})", name, subs.get_subs_slice(*symbols))
|
||||
}
|
||||
Content::RigidVar(name) => write!(f, "Rigid({:?})", name),
|
||||
Content::RigidAbleVar(name, symbol) => write!(f, "RigidAble({:?}, {:?})", name, symbol),
|
||||
|
@ -1437,7 +1437,7 @@ fn integer_type(
|
|||
|
||||
// define the type `Num.Integer Num.Signed64 := Num.Signed64`
|
||||
{
|
||||
let vars = AliasVariables::insert_into_subs(subs, [signed64], []);
|
||||
let vars = AliasVariables::insert_into_subs(subs, [signed64], [], []);
|
||||
subs.set_content(integer_signed64, {
|
||||
Content::Alias(Symbol::NUM_INTEGER, vars, signed64, AliasKind::Opaque)
|
||||
});
|
||||
|
@ -1445,7 +1445,7 @@ fn integer_type(
|
|||
|
||||
// define the type `Num.Num (Num.Integer Num.Signed64) := Num.Integer Num.Signed64`
|
||||
{
|
||||
let vars = AliasVariables::insert_into_subs(subs, [integer_signed64], []);
|
||||
let vars = AliasVariables::insert_into_subs(subs, [integer_signed64], [], []);
|
||||
subs.set_content(num_integer_signed64, {
|
||||
Content::Alias(Symbol::NUM_NUM, vars, integer_signed64, AliasKind::Opaque)
|
||||
});
|
||||
|
@ -1605,7 +1605,7 @@ fn float_type(
|
|||
|
||||
// define the type `Num.Float Num.Binary64 := Num.Binary64`
|
||||
{
|
||||
let vars = AliasVariables::insert_into_subs(subs, [binary64], []);
|
||||
let vars = AliasVariables::insert_into_subs(subs, [binary64], [], []);
|
||||
subs.set_content(float_binary64, {
|
||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, vars, binary64, AliasKind::Opaque)
|
||||
});
|
||||
|
@ -1613,7 +1613,7 @@ fn float_type(
|
|||
|
||||
// define the type `Num.Num (Num.Float Num.Binary64) := Num.Float Num.Binary64`
|
||||
{
|
||||
let vars = AliasVariables::insert_into_subs(subs, [float_binary64], []);
|
||||
let vars = AliasVariables::insert_into_subs(subs, [float_binary64], [], []);
|
||||
subs.set_content(num_float_binary64, {
|
||||
Content::Alias(Symbol::NUM_NUM, vars, float_binary64, AliasKind::Opaque)
|
||||
});
|
||||
|
@ -2269,8 +2269,8 @@ impl From<Content> for Descriptor {
|
|||
}
|
||||
|
||||
roc_error_macros::assert_sizeof_all!(Content, 4 * 8);
|
||||
roc_error_macros::assert_sizeof_all!((Symbol, AliasVariables, Variable), 2 * 8 + 4);
|
||||
roc_error_macros::assert_sizeof_all!(AliasVariables, 8);
|
||||
roc_error_macros::assert_sizeof_all!((Symbol, AliasVariables, Variable), 8 + 12 + 4);
|
||||
roc_error_macros::assert_sizeof_all!(AliasVariables, 12);
|
||||
roc_error_macros::assert_sizeof_all!(FlatType, 3 * 8);
|
||||
roc_error_macros::assert_sizeof_all!(LambdaSet, 3 * 8 + 4);
|
||||
|
||||
|
@ -2358,8 +2358,11 @@ pub struct LambdaSet {
|
|||
pub struct AliasVariables {
|
||||
pub variables_start: u32,
|
||||
pub all_variables_len: u16,
|
||||
pub lambda_set_variables_len: u16,
|
||||
|
||||
/// an alias has type variables and lambda set variables
|
||||
/// an alias has type variables, lambda set variables, and infer-ext-in-output-position variables.
|
||||
/// They are arranged as
|
||||
/// [ type variables | lambda set variables | infer ext variables ]
|
||||
pub type_variables_len: u16,
|
||||
}
|
||||
|
||||
|
@ -2373,10 +2376,16 @@ impl AliasVariables {
|
|||
}
|
||||
|
||||
pub const fn lambda_set_variables(&self) -> VariableSubsSlice {
|
||||
SubsSlice::new(
|
||||
self.variables_start + self.type_variables_len as u32,
|
||||
self.all_variables_len - self.type_variables_len,
|
||||
)
|
||||
let start = self.variables_start + self.type_variables_len as u32;
|
||||
SubsSlice::new(start, self.lambda_set_variables_len)
|
||||
}
|
||||
|
||||
pub const fn infer_ext_in_output_variables(&self) -> VariableSubsSlice {
|
||||
let infer_ext_vars_offset =
|
||||
self.type_variables_len as u32 + self.lambda_set_variables_len as u32;
|
||||
let start = self.variables_start + infer_ext_vars_offset;
|
||||
let infer_ext_vars_len = self.all_variables_len - infer_ext_vars_offset as u16;
|
||||
SubsSlice::new(start, infer_ext_vars_len)
|
||||
}
|
||||
|
||||
pub const fn len(&self) -> usize {
|
||||
|
@ -2407,20 +2416,23 @@ impl AliasVariables {
|
|||
.take(self.type_variables_len as usize)
|
||||
}
|
||||
|
||||
pub fn unnamed_type_arguments(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
||||
pub fn iter_lambda_set_variables(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
||||
self.all_variables()
|
||||
.into_iter()
|
||||
.skip(self.type_variables_len as usize)
|
||||
.take(self.lambda_set_variables_len as _)
|
||||
}
|
||||
|
||||
pub fn insert_into_subs<I1, I2>(
|
||||
pub fn insert_into_subs<I1, I2, I3>(
|
||||
subs: &mut Subs,
|
||||
type_arguments: I1,
|
||||
unnamed_arguments: I2,
|
||||
lambda_set_vars: I2,
|
||||
infer_ext_in_output_vars: I3,
|
||||
) -> Self
|
||||
where
|
||||
I1: IntoIterator<Item = Variable>,
|
||||
I2: IntoIterator<Item = Variable>,
|
||||
I3: IntoIterator<Item = Variable>,
|
||||
{
|
||||
let variables_start = subs.variables.len() as u32;
|
||||
|
||||
|
@ -2428,13 +2440,33 @@ impl AliasVariables {
|
|||
|
||||
let type_variables_len = (subs.variables.len() as u32 - variables_start) as u16;
|
||||
|
||||
subs.variables.extend(unnamed_arguments);
|
||||
let lambda_set_variables_len = {
|
||||
let start = subs.variables.len() as u32;
|
||||
|
||||
subs.variables.extend(lambda_set_vars);
|
||||
|
||||
(subs.variables.len() as u32 - start) as u16
|
||||
};
|
||||
|
||||
let _infer_ext_in_output_vars_len = {
|
||||
let start = subs.variables.len() as u32;
|
||||
|
||||
subs.variables.extend(infer_ext_in_output_vars);
|
||||
|
||||
(subs.variables.len() as u32 - start) as u16
|
||||
};
|
||||
|
||||
let all_variables_len = (subs.variables.len() as u32 - variables_start) as u16;
|
||||
|
||||
debug_assert_eq!(
|
||||
type_variables_len + lambda_set_variables_len + _infer_ext_in_output_vars_len,
|
||||
all_variables_len
|
||||
);
|
||||
|
||||
Self {
|
||||
variables_start,
|
||||
type_variables_len,
|
||||
lambda_set_variables_len,
|
||||
all_variables_len,
|
||||
}
|
||||
}
|
||||
|
@ -3800,7 +3832,7 @@ fn content_to_err_type(
|
|||
|
||||
let mut err_args = Vec::with_capacity(args.len());
|
||||
|
||||
for var_index in args.into_iter() {
|
||||
for var_index in args.type_variables() {
|
||||
let var = subs[var_index];
|
||||
|
||||
let arg = var_to_err_type(subs, state, var, pol);
|
||||
|
|
|
@ -172,19 +172,18 @@ impl RecordField<Type> {
|
|||
region: Region,
|
||||
aliases: &'a F,
|
||||
var_store: &mut VarStore,
|
||||
introduced: &mut ImSet<Variable>,
|
||||
new_lambda_sets: &mut ImSet<Variable>,
|
||||
new_infer_ext_vars: &mut ImSet<Variable>,
|
||||
) where
|
||||
F: Fn(Symbol) -> Option<&'a Alias>,
|
||||
{
|
||||
use RecordField::*;
|
||||
|
||||
match self {
|
||||
Optional(typ) => typ.instantiate_aliases(region, aliases, var_store, introduced),
|
||||
Required(typ) => typ.instantiate_aliases(region, aliases, var_store, introduced),
|
||||
Demanded(typ) => typ.instantiate_aliases(region, aliases, var_store, introduced),
|
||||
RigidRequired(typ) => typ.instantiate_aliases(region, aliases, var_store, introduced),
|
||||
RigidOptional(typ) => typ.instantiate_aliases(region, aliases, var_store, introduced),
|
||||
}
|
||||
self.as_inner_mut().instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_sets,
|
||||
new_infer_ext_vars,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn contains_symbol(&self, rep_symbol: Symbol) -> bool {
|
||||
|
@ -228,12 +227,18 @@ impl LambdaSet {
|
|||
region: Region,
|
||||
aliases: &'a F,
|
||||
var_store: &mut VarStore,
|
||||
introduced: &mut ImSet<Variable>,
|
||||
new_lambda_sets: &mut ImSet<Variable>,
|
||||
new_infer_ext_vars: &mut ImSet<Variable>,
|
||||
) where
|
||||
F: Fn(Symbol) -> Option<&'a Alias>,
|
||||
{
|
||||
self.0
|
||||
.instantiate_aliases(region, aliases, var_store, introduced)
|
||||
self.0.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_sets,
|
||||
new_infer_ext_vars,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,6 +247,7 @@ pub struct AliasCommon {
|
|||
pub symbol: Symbol,
|
||||
pub type_arguments: Vec<Loc<OptAbleType>>,
|
||||
pub lambda_set_variables: Vec<LambdaSet>,
|
||||
pub infer_ext_in_output_types: Vec<Type>,
|
||||
}
|
||||
|
||||
/// Represents a collection of abilities bound to a type variable.
|
||||
|
@ -394,6 +400,7 @@ pub enum Type {
|
|||
symbol: Symbol,
|
||||
type_arguments: Vec<OptAbleType>,
|
||||
lambda_set_variables: Vec<LambdaSet>,
|
||||
infer_ext_in_output_types: Vec<Type>,
|
||||
actual: Box<Type>,
|
||||
kind: AliasKind,
|
||||
},
|
||||
|
@ -476,12 +483,14 @@ impl Clone for Type {
|
|||
symbol,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: infer_ext_in_output_variables,
|
||||
actual,
|
||||
kind,
|
||||
} => Self::Alias {
|
||||
symbol: *symbol,
|
||||
type_arguments: type_arguments.clone(),
|
||||
lambda_set_variables: lambda_set_variables.clone(),
|
||||
infer_ext_in_output_types: infer_ext_in_output_variables.clone(),
|
||||
actual: actual.clone(),
|
||||
kind: *kind,
|
||||
},
|
||||
|
@ -631,6 +640,7 @@ impl fmt::Debug for Type {
|
|||
symbol,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
}) => {
|
||||
write!(f, "(DelayedAlias {:?}", symbol)?;
|
||||
|
||||
|
@ -644,6 +654,10 @@ impl fmt::Debug for Type {
|
|||
write!(f, " {}@{:?}", greek_letter, lambda_set.0)?;
|
||||
}
|
||||
|
||||
for (i, infer_ext) in infer_ext_in_output_types.iter().enumerate() {
|
||||
write!(f, " `{}@{:?}", i, infer_ext)?;
|
||||
}
|
||||
|
||||
write!(f, ")")?;
|
||||
|
||||
Ok(())
|
||||
|
@ -916,6 +930,7 @@ impl Type {
|
|||
Type::DelayedAlias(AliasCommon {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
..
|
||||
}) => {
|
||||
for value in type_arguments.iter_mut() {
|
||||
|
@ -925,10 +940,15 @@ impl Type {
|
|||
for lambda_set in lambda_set_variables.iter_mut() {
|
||||
stack.push(lambda_set.as_inner_mut());
|
||||
}
|
||||
|
||||
for infer_ext in infer_ext_in_output_types.iter_mut() {
|
||||
stack.push(infer_ext);
|
||||
}
|
||||
}
|
||||
Alias {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: infer_ext_in_output_variables,
|
||||
actual,
|
||||
..
|
||||
} => {
|
||||
|
@ -940,6 +960,10 @@ impl Type {
|
|||
stack.push(lambda_set.as_inner_mut());
|
||||
}
|
||||
|
||||
for infer_ext in infer_ext_in_output_variables.iter_mut() {
|
||||
stack.push(infer_ext);
|
||||
}
|
||||
|
||||
stack.push(actual);
|
||||
}
|
||||
HostExposedAlias {
|
||||
|
@ -1038,6 +1062,7 @@ impl Type {
|
|||
Type::DelayedAlias(AliasCommon {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
..
|
||||
}) => {
|
||||
for value in type_arguments.iter_mut() {
|
||||
|
@ -1047,10 +1072,15 @@ impl Type {
|
|||
for lambda_set in lambda_set_variables.iter_mut() {
|
||||
stack.push(lambda_set.as_inner_mut());
|
||||
}
|
||||
|
||||
for typ in infer_ext_in_output_types.iter_mut() {
|
||||
stack.push(typ);
|
||||
}
|
||||
}
|
||||
Alias {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
actual,
|
||||
..
|
||||
} => {
|
||||
|
@ -1060,6 +1090,9 @@ impl Type {
|
|||
for lambda_set in lambda_set_variables.iter_mut() {
|
||||
stack.push(lambda_set.as_inner_mut());
|
||||
}
|
||||
for typ in infer_ext_in_output_types.iter_mut() {
|
||||
stack.push(typ);
|
||||
}
|
||||
|
||||
stack.push(actual);
|
||||
}
|
||||
|
@ -1144,6 +1177,7 @@ impl Type {
|
|||
DelayedAlias(AliasCommon {
|
||||
type_arguments,
|
||||
lambda_set_variables: _no_aliases_in_lambda_sets,
|
||||
infer_ext_in_output_types: _no_aliases_in_infer_ext_types,
|
||||
..
|
||||
}) => {
|
||||
for ta in type_arguments {
|
||||
|
@ -1231,6 +1265,7 @@ impl Type {
|
|||
symbol,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: _,
|
||||
..
|
||||
}) => {
|
||||
symbol == &rep_symbol
|
||||
|
@ -1347,6 +1382,7 @@ impl Type {
|
|||
aliases: &'a F,
|
||||
var_store: &mut VarStore,
|
||||
new_lambda_set_variables: &mut ImSet<Variable>,
|
||||
new_infer_ext_vars: &mut ImSet<Variable>,
|
||||
) where
|
||||
F: Fn(Symbol) -> Option<&'a Alias>,
|
||||
{
|
||||
|
@ -1355,50 +1391,103 @@ impl Type {
|
|||
match self {
|
||||
Function(args, closure, ret) => {
|
||||
for arg in args {
|
||||
arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
arg.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
closure.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
ret.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
closure.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
ret.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
FunctionOrTagUnion(_, _, ext) => {
|
||||
if let TypeExtension::Open(ext) = ext {
|
||||
ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
ext.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
}
|
||||
RecursiveTagUnion(_, tags, ext) | TagUnion(tags, ext) => {
|
||||
for (_, args) in tags {
|
||||
for x in args {
|
||||
x.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
x.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let TypeExtension::Open(ext) = ext {
|
||||
ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
ext.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
}
|
||||
Record(fields, ext) => {
|
||||
for (_, x) in fields.iter_mut() {
|
||||
x.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
x.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
|
||||
if let TypeExtension::Open(ext) = ext {
|
||||
ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
ext.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
}
|
||||
DelayedAlias(AliasCommon {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
symbol: _,
|
||||
}) => {
|
||||
debug_assert!(lambda_set_variables
|
||||
.iter()
|
||||
.all(|lambda_set| matches!(lambda_set.0, Type::Variable(..))));
|
||||
debug_assert!(infer_ext_in_output_types
|
||||
.iter()
|
||||
.all(|t| matches!(t, Type::Variable(..) | Type::EmptyTagUnion)));
|
||||
type_arguments.iter_mut().for_each(|t| {
|
||||
t.value.typ.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
@ -1409,11 +1498,23 @@ impl Type {
|
|||
..
|
||||
} => {
|
||||
for arg in type_args {
|
||||
arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
arg.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
|
||||
for arg in lambda_set_variables {
|
||||
arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
arg.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
|
||||
actual_type.instantiate_aliases(
|
||||
|
@ -1421,6 +1522,7 @@ impl Type {
|
|||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
Alias {
|
||||
|
@ -1435,11 +1537,18 @@ impl Type {
|
|||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
|
||||
for arg in lambda_set_variables {
|
||||
arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables);
|
||||
arg.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
|
||||
actual_type.instantiate_aliases(
|
||||
|
@ -1447,12 +1556,14 @@ impl Type {
|
|||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
Apply(symbol, args, _) => {
|
||||
if let Some(alias) = aliases(*symbol) {
|
||||
// TODO switch to this, but we still need to check for recursion with the
|
||||
// `else` branch
|
||||
// `else` branch.
|
||||
// We would also need to determine polarity correct.
|
||||
if false {
|
||||
let mut type_var_to_arg = Vec::new();
|
||||
|
||||
|
@ -1477,10 +1588,20 @@ impl Type {
|
|||
lambda_set_variables.push(LambdaSet(Type::Variable(lvar)));
|
||||
}
|
||||
|
||||
let mut infer_ext_in_output_types =
|
||||
Vec::with_capacity(alias.infer_ext_in_output_variables.len());
|
||||
|
||||
for _ in 0..alias.infer_ext_in_output_variables.len() {
|
||||
let var = var_store.fresh();
|
||||
new_infer_ext_vars.insert(var);
|
||||
infer_ext_in_output_types.push(Type::Variable(var));
|
||||
}
|
||||
|
||||
let alias = Type::DelayedAlias(AliasCommon {
|
||||
symbol: *symbol,
|
||||
type_arguments: type_var_to_arg,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
});
|
||||
|
||||
*self = alias;
|
||||
|
@ -1521,6 +1642,7 @@ impl Type {
|
|||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
named_args.push(OptAbleType {
|
||||
typ: filler.value.clone(),
|
||||
|
@ -1542,12 +1664,21 @@ impl Type {
|
|||
unreachable!("at this point there should be only vars in there");
|
||||
}
|
||||
}
|
||||
let mut infer_ext_in_output_types =
|
||||
Vec::with_capacity(alias.infer_ext_in_output_variables.len());
|
||||
for var in alias.infer_ext_in_output_variables.iter() {
|
||||
let fresh = var_store.fresh();
|
||||
new_infer_ext_vars.insert(fresh);
|
||||
substitution.insert(*var, Type::Variable(fresh));
|
||||
infer_ext_in_output_types.push(Type::Variable(fresh));
|
||||
}
|
||||
|
||||
actual.instantiate_aliases(
|
||||
region,
|
||||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
|
||||
actual.substitute(&substitution);
|
||||
|
@ -1572,6 +1703,7 @@ impl Type {
|
|||
symbol: *symbol,
|
||||
type_arguments: named_args,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types,
|
||||
actual: Box::new(actual),
|
||||
kind: alias.kind,
|
||||
};
|
||||
|
@ -1586,6 +1718,7 @@ impl Type {
|
|||
aliases,
|
||||
var_store,
|
||||
new_lambda_set_variables,
|
||||
new_infer_ext_vars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1638,11 +1771,8 @@ impl Type {
|
|||
/// ```
|
||||
pub fn is_narrow(&self) -> bool {
|
||||
match self.shallow_dealias() {
|
||||
Type::TagUnion(tags, ext) | Type::RecursiveTagUnion(_, tags, ext) => {
|
||||
matches!(ext, TypeExtension::Closed)
|
||||
&& tags.len() == 1
|
||||
&& tags[0].1.len() == 1
|
||||
&& tags[0].1[0].is_narrow()
|
||||
Type::TagUnion(tags, _ext) | Type::RecursiveTagUnion(_, tags, _ext) => {
|
||||
tags.len() == 1 && tags[0].1.len() == 1 && tags[0].1[0].is_narrow()
|
||||
}
|
||||
Type::Record(fields, ext) => match ext {
|
||||
TypeExtension::Open(ext) => {
|
||||
|
@ -1957,6 +2087,7 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
|||
DelayedAlias(AliasCommon {
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: _,
|
||||
..
|
||||
}) => {
|
||||
for arg in type_arguments {
|
||||
|
@ -1974,6 +2105,7 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) {
|
|||
Alias {
|
||||
type_arguments,
|
||||
actual,
|
||||
infer_ext_in_output_types: _,
|
||||
..
|
||||
} => {
|
||||
for arg in type_arguments {
|
||||
|
@ -2245,6 +2377,10 @@ pub struct Alias {
|
|||
/// a |c|-> b
|
||||
pub lambda_set_variables: Vec<LambdaSet>,
|
||||
|
||||
/// Extension variables that should be inferred in output positions, and closed in input
|
||||
/// positions.
|
||||
pub infer_ext_in_output_variables: Vec<Variable>,
|
||||
|
||||
pub recursion_variables: MutSet<Variable>,
|
||||
|
||||
pub typ: Type,
|
||||
|
@ -3057,6 +3193,7 @@ fn instantiate_lambda_sets_as_unspecialized(
|
|||
symbol: _,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: _, // these are irrelevant for ULS instantiation, since they're inferred or closed
|
||||
}) => {
|
||||
for lambda_set in lambda_set_variables.iter_mut() {
|
||||
debug_assert!(matches!(lambda_set.0, Type::Variable(_)));
|
||||
|
@ -3068,6 +3205,7 @@ fn instantiate_lambda_sets_as_unspecialized(
|
|||
symbol: _,
|
||||
type_arguments,
|
||||
lambda_set_variables,
|
||||
infer_ext_in_output_types: _, // these are irrelevant for ULS instantiation, since they're inferred
|
||||
actual,
|
||||
kind: _,
|
||||
} => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue