mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
write Aliases implementation
This commit is contained in:
parent
a66d23f93d
commit
7d8409f6a6
7 changed files with 175 additions and 35 deletions
|
@ -1390,7 +1390,7 @@ fn adjust_rank_content(
|
||||||
Alias(_, args, real_var, _) => {
|
Alias(_, args, real_var, _) => {
|
||||||
let mut rank = Rank::toplevel();
|
let mut rank = Rank::toplevel();
|
||||||
|
|
||||||
for var_index in args.variables() {
|
for var_index in args.all_variables() {
|
||||||
let var = subs[var_index];
|
let var = subs[var_index];
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
||||||
}
|
}
|
||||||
|
@ -1548,7 +1548,7 @@ fn instantiate_rigids_help(
|
||||||
}
|
}
|
||||||
|
|
||||||
Alias(_, args, real_type_var, _) => {
|
Alias(_, args, real_type_var, _) => {
|
||||||
for var_index in args.variables() {
|
for var_index in args.all_variables() {
|
||||||
let var = subs[var_index];
|
let var = subs[var_index];
|
||||||
instantiate_rigids_help(subs, max_rank, pools, var);
|
instantiate_rigids_help(subs, max_rank, pools, var);
|
||||||
}
|
}
|
||||||
|
@ -1798,9 +1798,9 @@ fn deep_copy_var_help(
|
||||||
}
|
}
|
||||||
|
|
||||||
Alias(symbol, mut args, real_type_var, kind) => {
|
Alias(symbol, mut args, real_type_var, kind) => {
|
||||||
let mut new_args = Vec::with_capacity(args.variables().len());
|
let mut new_args = Vec::with_capacity(args.all_variables().len());
|
||||||
|
|
||||||
for var_index in args.variables() {
|
for var_index in args.all_variables() {
|
||||||
let var = subs[var_index];
|
let var = subs[var_index];
|
||||||
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
|
let new_var = deep_copy_var_help(subs, max_rank, pools, var);
|
||||||
new_args.push(new_var);
|
new_args.push(new_var);
|
||||||
|
|
|
@ -8446,7 +8446,7 @@ pub fn num_argument_to_int_or_float(
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
// Recurse on the second argument
|
// Recurse on the second argument
|
||||||
let var = subs[args.variables().into_iter().next().unwrap()];
|
let var = subs[args.all_variables().into_iter().next().unwrap()];
|
||||||
num_argument_to_int_or_float(subs, target_info, var, false)
|
num_argument_to_int_or_float(subs, target_info, var, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8464,7 +8464,7 @@ pub fn num_argument_to_int_or_float(
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
// Recurse on the second argument
|
// Recurse on the second argument
|
||||||
let var = subs[args.variables().into_iter().next().unwrap()];
|
let var = subs[args.all_variables().into_iter().next().unwrap()];
|
||||||
num_argument_to_int_or_float(subs, target_info, var, true)
|
num_argument_to_int_or_float(subs, target_info, var, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2670,7 +2670,7 @@ fn unwrap_num_tag<'a>(
|
||||||
Content::Alias(Symbol::NUM_INTEGER, args, _, _) => {
|
Content::Alias(Symbol::NUM_INTEGER, args, _, _) => {
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
let precision_var = subs[args.variables().into_iter().next().unwrap()];
|
let precision_var = subs[args.all_variables().into_iter().next().unwrap()];
|
||||||
|
|
||||||
let precision = subs.get_content_without_compacting(precision_var);
|
let precision = subs.get_content_without_compacting(precision_var);
|
||||||
|
|
||||||
|
@ -2706,7 +2706,7 @@ fn unwrap_num_tag<'a>(
|
||||||
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _, _) => {
|
Content::Alias(Symbol::NUM_FLOATINGPOINT, args, _, _) => {
|
||||||
debug_assert!(args.len() == 1);
|
debug_assert!(args.len() == 1);
|
||||||
|
|
||||||
let precision_var = subs[args.variables().into_iter().next().unwrap()];
|
let precision_var = subs[args.all_variables().into_iter().next().unwrap()];
|
||||||
|
|
||||||
let precision = subs.get_content_without_compacting(precision_var);
|
let precision = subs.get_content_without_compacting(precision_var);
|
||||||
|
|
||||||
|
|
|
@ -78,27 +78,142 @@ pub enum TypeError {
|
||||||
|
|
||||||
use roc_types::types::Alias;
|
use roc_types::types::Alias;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct DelayedAliasVariables {
|
||||||
|
start: u32,
|
||||||
|
type_variables_len: u8,
|
||||||
|
lambda_set_variables_len: u8,
|
||||||
|
recursion_variables_len: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DelayedAliasVariables {
|
||||||
|
fn recursion_variables(self, variables: &mut [Variable]) -> &mut [Variable] {
|
||||||
|
let start = self.start as usize
|
||||||
|
+ (self.type_variables_len + self.lambda_set_variables_len) as usize;
|
||||||
|
let length = self.recursion_variables_len as usize;
|
||||||
|
|
||||||
|
&mut variables[start..][..length]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lambda_set_variables(self, variables: &mut [Variable]) -> &mut [Variable] {
|
||||||
|
let start = self.start as usize + self.type_variables_len as usize;
|
||||||
|
let length = self.lambda_set_variables_len as usize;
|
||||||
|
|
||||||
|
&mut variables[start..][..length]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_variables(self, variables: &mut [Variable]) -> &mut [Variable] {
|
||||||
|
let start = self.start as usize;
|
||||||
|
let length = self.type_variables_len as usize;
|
||||||
|
|
||||||
|
&mut variables[start..][..length]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Aliases {
|
pub struct Aliases {
|
||||||
aliases: MutMap<Symbol, Alias>,
|
aliases: Vec<(Symbol, Type, DelayedAliasVariables)>,
|
||||||
|
variables: Vec<Variable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Aliases {
|
impl Aliases {
|
||||||
fn instantiate_alias(
|
pub fn insert(&mut self, symbol: Symbol, alias: Alias) {
|
||||||
&self,
|
// debug_assert!(self.get(&symbol).is_none());
|
||||||
|
|
||||||
|
let alias_variables =
|
||||||
|
{
|
||||||
|
let start = self.variables.len() as _;
|
||||||
|
|
||||||
|
self.variables
|
||||||
|
.extend(alias.type_variables.iter().map(|x| x.value.1));
|
||||||
|
|
||||||
|
self.variables.extend(alias.lambda_set_variables.iter().map(
|
||||||
|
|x| match x.as_inner() {
|
||||||
|
Type::Variable(v) => *v,
|
||||||
|
_ => unreachable!("lambda set type is not a variable"),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
let recursion_variables_len = alias.recursion_variables.len() as _;
|
||||||
|
self.variables.extend(alias.recursion_variables);
|
||||||
|
|
||||||
|
DelayedAliasVariables {
|
||||||
|
start,
|
||||||
|
type_variables_len: alias.type_variables.len() as _,
|
||||||
|
lambda_set_variables_len: alias.lambda_set_variables.len() as _,
|
||||||
|
recursion_variables_len,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.aliases.push((symbol, alias.typ, alias_variables));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate(
|
||||||
|
&mut self,
|
||||||
subs: &mut Subs,
|
subs: &mut Subs,
|
||||||
rank: Rank,
|
rank: Rank,
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
arena: &bumpalo::Bump,
|
_arena: &bumpalo::Bump,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
alias_variables: AliasVariables,
|
alias_variables: AliasVariables,
|
||||||
) -> Result<Variable, ()> {
|
) -> Result<Variable, ()> {
|
||||||
match self.aliases.get(&symbol) {
|
let (typ, delayed_variables) = match self.aliases.iter_mut().find(|(s, _, _)| *s == symbol)
|
||||||
None => Err(()),
|
{
|
||||||
Some(alias) => {
|
None => return Err(()),
|
||||||
todo!()
|
Some((_, typ, delayed_variables)) => (typ, delayed_variables),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut substitutions: MutMap<_, _> = Default::default();
|
||||||
|
|
||||||
|
for rec_var in delayed_variables
|
||||||
|
.recursion_variables(&mut self.variables)
|
||||||
|
.iter_mut()
|
||||||
|
{
|
||||||
|
let new_var = subs.fresh_unnamed_flex_var();
|
||||||
|
substitutions.insert(*rec_var, new_var);
|
||||||
|
*rec_var = new_var;
|
||||||
|
}
|
||||||
|
|
||||||
|
let old_type_variables = delayed_variables.type_variables(&mut self.variables);
|
||||||
|
let new_type_variables = &subs.variables[alias_variables.type_variables().indices()];
|
||||||
|
|
||||||
|
for (old, new) in old_type_variables.iter_mut().zip(new_type_variables) {
|
||||||
|
substitutions.insert(*old, *new);
|
||||||
|
*old = *new;
|
||||||
|
}
|
||||||
|
|
||||||
|
let old_lambda_set_variables = delayed_variables.lambda_set_variables(&mut self.variables);
|
||||||
|
let new_lambda_set_variables =
|
||||||
|
&subs.variables[alias_variables.lambda_set_variables().indices()];
|
||||||
|
|
||||||
|
for (old, new) in old_lambda_set_variables
|
||||||
|
.iter_mut()
|
||||||
|
.zip(new_lambda_set_variables)
|
||||||
|
{
|
||||||
|
substitutions.insert(*old, *new);
|
||||||
|
*old = *new;
|
||||||
|
}
|
||||||
|
|
||||||
|
typ.substitute_variables(&substitutions);
|
||||||
|
|
||||||
|
// assumption: an alias does not (transitively) syntactically contain itself
|
||||||
|
// (if it did it would have to be a recursive tag union)
|
||||||
|
let mut t = Type::EmptyRec;
|
||||||
|
|
||||||
|
std::mem::swap(typ, &mut t);
|
||||||
|
|
||||||
|
let alias_variable = type_to_var(subs, rank, pools, self, &t);
|
||||||
|
|
||||||
|
{
|
||||||
|
match self.aliases.iter_mut().find(|(s, _, _)| *s == symbol) {
|
||||||
|
None => unreachable!(),
|
||||||
|
Some((_, typ, _)) => {
|
||||||
|
std::mem::swap(typ, &mut t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(alias_variable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +1047,7 @@ fn type_to_var(
|
||||||
subs: &mut Subs,
|
subs: &mut Subs,
|
||||||
rank: Rank,
|
rank: Rank,
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
aliases: &Aliases,
|
aliases: &mut Aliases,
|
||||||
typ: &Type,
|
typ: &Type,
|
||||||
) -> Variable {
|
) -> Variable {
|
||||||
if let Type::Variable(var) = typ {
|
if let Type::Variable(var) = typ {
|
||||||
|
@ -1020,7 +1135,7 @@ fn type_to_variable<'a>(
|
||||||
rank: Rank,
|
rank: Rank,
|
||||||
pools: &mut Pools,
|
pools: &mut Pools,
|
||||||
arena: &'a bumpalo::Bump,
|
arena: &'a bumpalo::Bump,
|
||||||
aliases: &Aliases,
|
aliases: &mut Aliases,
|
||||||
typ: &Type,
|
typ: &Type,
|
||||||
) -> Variable {
|
) -> Variable {
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
|
@ -1226,7 +1341,7 @@ fn type_to_variable<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let instantiated =
|
let instantiated =
|
||||||
aliases.instantiate_alias(subs, rank, pools, arena, *symbol, alias_variables);
|
aliases.instantiate(subs, rank, pools, arena, *symbol, alias_variables);
|
||||||
|
|
||||||
let alias_variable = match instantiated {
|
let alias_variable = match instantiated {
|
||||||
Err(_) => panic!("Alias {:?} is not available", symbol),
|
Err(_) => panic!("Alias {:?} is not available", symbol),
|
||||||
|
@ -1943,7 +2058,7 @@ fn adjust_rank_content(
|
||||||
Alias(_, args, real_var, _) => {
|
Alias(_, args, real_var, _) => {
|
||||||
let mut rank = Rank::toplevel();
|
let mut rank = Rank::toplevel();
|
||||||
|
|
||||||
for var_index in args.variables() {
|
for var_index in args.all_variables() {
|
||||||
let var = subs[var_index];
|
let var = subs[var_index];
|
||||||
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
rank = rank.max(adjust_rank(subs, young_mark, visit_mark, group_rank, var));
|
||||||
}
|
}
|
||||||
|
@ -2089,7 +2204,7 @@ fn instantiate_rigids_help(subs: &mut Subs, max_rank: Rank, initial: Variable) {
|
||||||
let var = *var;
|
let var = *var;
|
||||||
let args = *args;
|
let args = *args;
|
||||||
|
|
||||||
stack.extend(var_slice!(args.variables()));
|
stack.extend(var_slice!(args.all_variables()));
|
||||||
|
|
||||||
stack.push(var);
|
stack.push(var);
|
||||||
}
|
}
|
||||||
|
@ -2338,7 +2453,9 @@ fn deep_copy_var_help(
|
||||||
Alias(symbol, arguments, real_type_var, kind) => {
|
Alias(symbol, arguments, real_type_var, kind) => {
|
||||||
let new_variables =
|
let new_variables =
|
||||||
SubsSlice::reserve_into_subs(subs, arguments.all_variables_len as _);
|
SubsSlice::reserve_into_subs(subs, arguments.all_variables_len as _);
|
||||||
for (target_index, var_index) in (new_variables.indices()).zip(arguments.variables()) {
|
for (target_index, var_index) in
|
||||||
|
(new_variables.indices()).zip(arguments.all_variables())
|
||||||
|
{
|
||||||
let var = subs[var_index];
|
let var = subs[var_index];
|
||||||
let copy_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
let copy_var = deep_copy_var_help(subs, max_rank, pools, visited, var);
|
||||||
subs.variables[target_index] = copy_var;
|
subs.variables[target_index] = copy_var;
|
||||||
|
|
|
@ -427,7 +427,7 @@ fn subs_fmt_content(this: &Content, subs: &Subs, f: &mut fmt::Formatter) -> fmt:
|
||||||
} => write!(f, "Recursion({:?}, {:?})", structure, opt_name),
|
} => write!(f, "Recursion({:?}, {:?})", structure, opt_name),
|
||||||
Content::Structure(flat_type) => subs_fmt_flat_type(flat_type, subs, f),
|
Content::Structure(flat_type) => subs_fmt_flat_type(flat_type, subs, f),
|
||||||
Content::Alias(name, arguments, actual, kind) => {
|
Content::Alias(name, arguments, actual, kind) => {
|
||||||
let slice = subs.get_subs_slice(arguments.variables());
|
let slice = subs.get_subs_slice(arguments.all_variables());
|
||||||
let wrap = match kind {
|
let wrap = match kind {
|
||||||
AliasKind::Structural => "Alias",
|
AliasKind::Structural => "Alias",
|
||||||
AliasKind::Opaque => "Opaque",
|
AliasKind::Opaque => "Opaque",
|
||||||
|
@ -1775,10 +1775,21 @@ pub struct AliasVariables {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AliasVariables {
|
impl AliasVariables {
|
||||||
pub const fn variables(&self) -> VariableSubsSlice {
|
pub const fn all_variables(&self) -> VariableSubsSlice {
|
||||||
SubsSlice::new(self.variables_start, self.all_variables_len)
|
SubsSlice::new(self.variables_start, self.all_variables_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn type_variables(&self) -> VariableSubsSlice {
|
||||||
|
SubsSlice::new(self.variables_start, self.type_variables_len)
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn len(&self) -> usize {
|
pub const fn len(&self) -> usize {
|
||||||
self.type_variables_len as usize
|
self.type_variables_len as usize
|
||||||
}
|
}
|
||||||
|
@ -1802,13 +1813,13 @@ impl AliasVariables {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn named_type_arguments(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
pub fn named_type_arguments(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
||||||
self.variables()
|
self.all_variables()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.take(self.type_variables_len as usize)
|
.take(self.type_variables_len as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unnamed_type_arguments(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
pub fn unnamed_type_arguments(&self) -> impl Iterator<Item = SubsIndex<Variable>> {
|
||||||
self.variables()
|
self.all_variables()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.skip(self.type_variables_len as usize)
|
.skip(self.type_variables_len as usize)
|
||||||
}
|
}
|
||||||
|
@ -1850,7 +1861,7 @@ impl IntoIterator for AliasVariables {
|
||||||
type IntoIter = <VariableSubsSlice as IntoIterator>::IntoIter;
|
type IntoIter = <VariableSubsSlice as IntoIterator>::IntoIter;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
self.variables().into_iter()
|
self.all_variables().into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3298,7 +3309,7 @@ fn restore_help(subs: &mut Subs, initial: Variable) {
|
||||||
Erroneous(_) => (),
|
Erroneous(_) => (),
|
||||||
},
|
},
|
||||||
Alias(_, args, var, _) => {
|
Alias(_, args, var, _) => {
|
||||||
stack.extend(var_slice(args.variables()));
|
stack.extend(var_slice(args.all_variables()));
|
||||||
|
|
||||||
stack.push(*var);
|
stack.push(*var);
|
||||||
}
|
}
|
||||||
|
@ -3333,6 +3344,14 @@ impl StorageSubs {
|
||||||
Self { subs }
|
Self { subs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fresh_unnamed_flex_var(&mut self) -> Variable {
|
||||||
|
self.subs.fresh_unnamed_flex_var()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_inner_mut(&mut self) -> &mut Subs {
|
||||||
|
&mut self.subs
|
||||||
|
}
|
||||||
|
|
||||||
pub fn extend_with_variable(&mut self, source: &mut Subs, variable: Variable) -> Variable {
|
pub fn extend_with_variable(&mut self, source: &mut Subs, variable: Variable) -> Variable {
|
||||||
deep_copy_var_to(source, &mut self.subs, variable)
|
deep_copy_var_to(source, &mut self.subs, variable)
|
||||||
}
|
}
|
||||||
|
@ -3867,7 +3886,9 @@ fn deep_copy_var_to_help<'a>(env: &mut DeepCopyVarToEnv<'a>, var: Variable) -> V
|
||||||
Alias(symbol, arguments, real_type_var, kind) => {
|
Alias(symbol, arguments, real_type_var, kind) => {
|
||||||
let new_variables =
|
let new_variables =
|
||||||
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
|
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
|
||||||
for (target_index, var_index) in (new_variables.indices()).zip(arguments.variables()) {
|
for (target_index, var_index) in
|
||||||
|
(new_variables.indices()).zip(arguments.all_variables())
|
||||||
|
{
|
||||||
let var = env.source[var_index];
|
let var = env.source[var_index];
|
||||||
let copy_var = deep_copy_var_to_help(env, var);
|
let copy_var = deep_copy_var_to_help(env, var);
|
||||||
env.target.variables[target_index] = copy_var;
|
env.target.variables[target_index] = copy_var;
|
||||||
|
@ -4284,7 +4305,9 @@ fn copy_import_to_help(env: &mut CopyImportEnv<'_>, max_rank: Rank, var: Variabl
|
||||||
Alias(symbol, arguments, real_type_var, kind) => {
|
Alias(symbol, arguments, real_type_var, kind) => {
|
||||||
let new_variables =
|
let new_variables =
|
||||||
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
|
SubsSlice::reserve_into_subs(env.target, arguments.all_variables_len as _);
|
||||||
for (target_index, var_index) in (new_variables.indices()).zip(arguments.variables()) {
|
for (target_index, var_index) in
|
||||||
|
(new_variables.indices()).zip(arguments.all_variables())
|
||||||
|
{
|
||||||
let var = env.source[var_index];
|
let var = env.source[var_index];
|
||||||
let copy_var = copy_import_to_help(env, max_rank, var);
|
let copy_var = copy_import_to_help(env, max_rank, var);
|
||||||
env.target.variables[target_index] = copy_var;
|
env.target.variables[target_index] = copy_var;
|
||||||
|
@ -4389,7 +4412,7 @@ where
|
||||||
Erroneous(_) | EmptyRecord | EmptyTagUnion => {}
|
Erroneous(_) | EmptyRecord | EmptyTagUnion => {}
|
||||||
},
|
},
|
||||||
Alias(_, arguments, real_type_var, _) => {
|
Alias(_, arguments, real_type_var, _) => {
|
||||||
push_var_slice!(arguments.variables());
|
push_var_slice!(arguments.all_variables());
|
||||||
stack.push(*real_type_var);
|
stack.push(*real_type_var);
|
||||||
}
|
}
|
||||||
RangedNumber(typ, vars) => {
|
RangedNumber(typ, vars) => {
|
||||||
|
|
|
@ -160,8 +160,8 @@ impl RecordField<Type> {
|
||||||
pub struct LambdaSet(pub Type);
|
pub struct LambdaSet(pub Type);
|
||||||
|
|
||||||
impl LambdaSet {
|
impl LambdaSet {
|
||||||
fn substitute(&mut self, substitutions: &ImMap<Variable, Type>) {
|
pub fn as_inner(&self) -> &Type {
|
||||||
self.0.substitute(substitutions);
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_inner_mut(&mut self) -> &mut Type {
|
fn as_inner_mut(&mut self) -> &mut Type {
|
||||||
|
|
|
@ -322,9 +322,9 @@ fn unify_alias(
|
||||||
if args.len() == other_args.len() {
|
if args.len() == other_args.len() {
|
||||||
let mut problems = Vec::new();
|
let mut problems = Vec::new();
|
||||||
let it = args
|
let it = args
|
||||||
.variables()
|
.all_variables()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(other_args.variables().into_iter());
|
.zip(other_args.all_variables().into_iter());
|
||||||
|
|
||||||
for (l, r) in it {
|
for (l, r) in it {
|
||||||
let l_var = subs[l];
|
let l_var = subs[l];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue