From fc83865465ca83fe01f273bd314c7ee893b27ccf Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 18:53:17 +0100 Subject: [PATCH 1/9] deal with the lambda set in more cases --- compiler/types/src/types.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index fd8d9e12f0..a28507db15 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -886,7 +886,11 @@ impl Type { TypeExtension::Closed => Ok(()), } } - DelayedAlias(AliasCommon { type_arguments, .. }) => { + DelayedAlias(AliasCommon { + type_arguments, + lambda_set_variables, + .. + }) => { for (_, ta) in type_arguments { ta.substitute_alias(rep_symbol, rep_args, actual)?; } @@ -966,12 +970,16 @@ impl Type { DelayedAlias(AliasCommon { symbol, type_arguments, + lambda_set_variables, .. }) => { symbol == &rep_symbol || type_arguments .iter() .any(|v| v.1.contains_symbol(rep_symbol)) + || lambda_set_variables + .iter() + .any(|v| v.0.contains_symbol(rep_symbol)) } Alias { symbol: alias_symbol, @@ -1406,10 +1414,18 @@ fn variables_help(tipe: &Type, accum: &mut ImSet) { // this rec var doesn't need to be in flex_vars or rigid_vars accum.remove(rec); } - DelayedAlias(AliasCommon { type_arguments, .. }) => { + DelayedAlias(AliasCommon { + type_arguments, + lambda_set_variables, + .. + }) => { for (_, arg) in type_arguments { variables_help(arg, accum); } + + for lambda_set in lambda_set_variables { + variables_help(&lambda_set.0, accum); + } } Alias { type_arguments, @@ -1530,10 +1546,22 @@ fn variables_help_detailed(tipe: &Type, accum: &mut VariableDetail) { accum.recursion_variables.insert(*rec); } - DelayedAlias(AliasCommon { type_arguments, .. }) => { + DelayedAlias(AliasCommon { + type_arguments, + lambda_set_variables, + .. + }) => { for (_, arg) in type_arguments { variables_help_detailed(arg, accum); } + + for lambda_set in lambda_set_variables { + if let Type::Variable(v) = lambda_set.0 { + accum.lambda_set_variables.push(v); + } else { + variables_help_detailed(&lambda_set.0, accum); + } + } } Alias { type_arguments, From a4ce6815d2872876f518f0388a6a3877ebc8a0d1 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:03:03 +0100 Subject: [PATCH 2/9] clarify variable name --- compiler/types/src/types.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index a28507db15..8c2a7092c9 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -1063,41 +1063,41 @@ impl Type { region: Region, aliases: &ImMap, var_store: &mut VarStore, - introduced: &mut ImSet, + lambda_set_variables: &mut ImSet, ) { use Type::*; match self { Function(args, closure, ret) => { for arg in args { - arg.instantiate_aliases(region, aliases, var_store, introduced); + arg.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } - closure.instantiate_aliases(region, aliases, var_store, introduced); - ret.instantiate_aliases(region, aliases, var_store, introduced); + closure.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + ret.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } FunctionOrTagUnion(_, _, ext) => { if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, introduced); + ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } } RecursiveTagUnion(_, tags, ext) | TagUnion(tags, ext) => { for (_, args) in tags { for x in args { - x.instantiate_aliases(region, aliases, var_store, introduced); + x.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } } if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, introduced); + ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } } Record(fields, ext) => { for (_, x) in fields.iter_mut() { - x.instantiate_aliases(region, aliases, var_store, introduced); + x.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, introduced); + ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); } } DelayedAlias(AliasCommon { .. }) => { From d6f0005fb3d4be1e5a897c519278d5b95a07bd72 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:04:07 +0100 Subject: [PATCH 3/9] bubble up lambda sets used by inner aliases --- compiler/can/src/def.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/can/src/def.rs b/compiler/can/src/def.rs index 7d1c03d58e..9f7886d55d 100644 --- a/compiler/can/src/def.rs +++ b/compiler/can/src/def.rs @@ -22,6 +22,7 @@ use roc_problem::can::{CycleEntry, Problem, RuntimeError}; use roc_region::all::{Loc, Region}; use roc_types::subs::{VarStore, Variable}; use roc_types::types::AliasKind; +use roc_types::types::LambdaSet; use roc_types::types::{Alias, Type}; use std::collections::HashMap; use std::fmt::Debug; @@ -1703,12 +1704,21 @@ fn correct_mutual_recursive_type_alias<'a>( let alias = pending_aliases.get_mut(&rec).unwrap(); // Don't try to instantiate the alias itself in its definition. let original_alias_def = to_instantiate.remove(&rec).unwrap(); + + let mut new_lambda_sets = ImSet::default(); alias.typ.instantiate_aliases( alias.region, &to_instantiate, var_store, - &mut ImSet::default(), + &mut new_lambda_sets, ); + + for lambda_set_var in new_lambda_sets { + alias + .lambda_set_variables + .push(LambdaSet(Type::Variable(lambda_set_var))); + } + to_instantiate.insert(rec, original_alias_def); // Now mark the alias recursive, if it needs to be. From 0b74fcd07b20c2e6129e2ae3106a636589b33689 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:10:49 +0100 Subject: [PATCH 4/9] add test of alias of alias with type variables but without lambda set --- compiler/test_gen/src/gen_primitives.rs | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/compiler/test_gen/src/gen_primitives.rs b/compiler/test_gen/src/gen_primitives.rs index 04d8a122e3..4b44d4c159 100644 --- a/compiler/test_gen/src/gen_primitives.rs +++ b/compiler/test_gen/src/gen_primitives.rs @@ -1908,6 +1908,35 @@ fn wildcard_rigid() { ); } +#[test] +#[cfg(any(feature = "gen-llvm"))] +fn alias_of_alias_with_type_arguments() { + assert_non_opt_evals_to!( + indoc!( + r#" + app "test" provides [ main ] to "./platform" + + Effect a : [ @Effect a ] + + Task a err : Effect (Result a err) + + always : a -> Task a * + always = \x -> + inner = (Ok x) + + @Effect inner + + + main : Task {} (Float *) + main = always {} + "# + ), + 0, + i64, + |_| 0 + ); +} + #[test] #[cfg(any(feature = "gen-llvm"))] #[ignore] From 83225cc469f2281d4ee4040ecd8a11e8916f7eec Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:11:55 +0100 Subject: [PATCH 5/9] ensure lambda set variables are freshly instantiated when instantiating an alias --- compiler/can/src/annotation.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/compiler/can/src/annotation.rs b/compiler/can/src/annotation.rs index 9fa5385640..c809ea7f05 100644 --- a/compiler/can/src/annotation.rs +++ b/compiler/can/src/annotation.rs @@ -348,7 +348,7 @@ fn can_annotation_help( // and this totally should be possible in the future. let is_import = !symbol.is_builtin() && (env.home != symbol.module_id()); let is_structural = alias.kind == AliasKind::Structural; - if !is_import && is_structural && alias.lambda_set_variables.is_empty() { + if !is_import && is_structural { let mut type_var_to_arg = Vec::new(); for (loc_var, arg_ann) in alias.type_variables.iter().zip(args) { @@ -357,10 +357,21 @@ fn can_annotation_help( type_var_to_arg.push((name, arg_ann)); } + let mut lambda_set_variables = + Vec::with_capacity(alias.lambda_set_variables.len()); + + for _ in 0..alias.lambda_set_variables.len() { + let lvar = var_store.fresh(); + + introduced_variables.insert_lambda_set(lvar); + + lambda_set_variables.push(LambdaSet(Type::Variable(lvar))); + } + Type::DelayedAlias(AliasCommon { symbol, type_arguments: type_var_to_arg, - lambda_set_variables: alias.lambda_set_variables.clone(), + lambda_set_variables, }) } else { let (type_arguments, lambda_set_variables, actual) = From 2b2db5e4fe49afba0f9ae4bb5a739453c7a74cd2 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:13:48 +0100 Subject: [PATCH 6/9] fix variable name --- compiler/types/src/types.rs | 74 +++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index 8c2a7092c9..181c090be1 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -1063,41 +1063,41 @@ impl Type { region: Region, aliases: &ImMap, var_store: &mut VarStore, - lambda_set_variables: &mut ImSet, + new_lambda_set_variables: &mut ImSet, ) { use Type::*; match self { Function(args, closure, ret) => { for arg in args { - arg.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } - closure.instantiate_aliases(region, aliases, var_store, lambda_set_variables); - ret.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + closure.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); + ret.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } FunctionOrTagUnion(_, _, ext) => { if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } } RecursiveTagUnion(_, tags, ext) | TagUnion(tags, ext) => { for (_, args) in tags { for x in args { - x.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + x.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } } if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } } Record(fields, ext) => { for (_, x) in fields.iter_mut() { - x.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + x.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } if let TypeExtension::Open(ext) = ext { - ext.instantiate_aliases(region, aliases, var_store, lambda_set_variables); + ext.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } } DelayedAlias(AliasCommon { .. }) => { @@ -1117,17 +1117,53 @@ impl Type { } => { for arg in type_args { arg.1 - .instantiate_aliases(region, aliases, var_store, introduced); + .instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } for arg in lambda_set_variables { - arg.instantiate_aliases(region, aliases, var_store, introduced); + arg.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } - actual_type.instantiate_aliases(region, aliases, var_store, introduced); + actual_type.instantiate_aliases( + region, + aliases, + var_store, + new_lambda_set_variables, + ); } Apply(symbol, args, _) => { if let Some(alias) = aliases.get(symbol) { + if true { + let mut type_var_to_arg = Vec::new(); + + for (loc_var, arg_ann) in alias.type_variables.iter().zip(args) { + let name = loc_var.value.0.clone(); + + type_var_to_arg.push((name, arg_ann.clone())); + } + + let mut lambda_set_variables = + Vec::with_capacity(alias.lambda_set_variables.len()); + + for _ in 0..alias.lambda_set_variables.len() { + let lvar = var_store.fresh(); + + new_lambda_set_variables.insert(lvar); + + lambda_set_variables.push(LambdaSet(Type::Variable(lvar))); + } + + let alias = Type::DelayedAlias(AliasCommon { + symbol: *symbol, + type_arguments: type_var_to_arg, + lambda_set_variables, + }); + + *self = alias; + } else { + todo!() + } + /* if args.len() != alias.type_variables.len() { *self = Type::Erroneous(Problem::BadTypeArguments { symbol: *symbol, @@ -1172,6 +1208,8 @@ impl Type { } } + dbg!(&actual); + actual.instantiate_aliases(region, aliases, var_store, introduced); actual.substitute(&substitution); @@ -1192,23 +1230,27 @@ impl Type { actual = Type::RecursiveTagUnion(new_rec_var, tags, ext); } - - *self = Type::Alias { + let alias = Type::Alias { symbol: *symbol, type_arguments: named_args, lambda_set_variables, actual: Box::new(actual), kind: alias.kind, }; + + dbg!(&alias); + + *self = alias; + */ } else { // one of the special-cased Apply types. for x in args { - x.instantiate_aliases(region, aliases, var_store, introduced); + x.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } } } RangedNumber(typ, _) => { - typ.instantiate_aliases(region, aliases, var_store, introduced); + typ.instantiate_aliases(region, aliases, var_store, new_lambda_set_variables); } EmptyRec | EmptyTagUnion | ClosureTag { .. } | Erroneous(_) | Variable(_) => {} } From 5196ae9df2b36d3b3adf5f917d41aac5399ec59d Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:20:22 +0100 Subject: [PATCH 7/9] use old alias instantiation when checking for invalid recursion --- compiler/types/src/types.rs | 155 +++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 75 deletions(-) diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index 181c090be1..7ac39697d0 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -1133,7 +1133,9 @@ impl Type { } Apply(symbol, args, _) => { if let Some(alias) = aliases.get(symbol) { - if true { + // TODO switch to this, but we still need to check for recursion with the + // `else` branch + if false { let mut type_var_to_arg = Vec::new(); for (loc_var, arg_ann) in alias.type_variables.iter().zip(args) { @@ -1161,87 +1163,90 @@ impl Type { *self = alias; } else { - todo!() - } - /* - if args.len() != alias.type_variables.len() { - *self = Type::Erroneous(Problem::BadTypeArguments { - symbol: *symbol, + if args.len() != alias.type_variables.len() { + *self = Type::Erroneous(Problem::BadTypeArguments { + symbol: *symbol, + region, + type_got: args.len() as u8, + alias_needs: alias.type_variables.len() as u8, + }); + return; + } + + let mut actual = alias.typ.clone(); + + let mut named_args = Vec::with_capacity(args.len()); + let mut substitution = ImMap::default(); + + // TODO substitute further in args + for ( + Loc { + value: (lowercase, placeholder), + .. + }, + filler, + ) in alias.type_variables.iter().zip(args.iter()) + { + let mut filler = filler.clone(); + filler.instantiate_aliases( + region, + aliases, + var_store, + new_lambda_set_variables, + ); + named_args.push((lowercase.clone(), filler.clone())); + substitution.insert(*placeholder, filler); + } + + // make sure hidden variables are freshly instantiated + let mut lambda_set_variables = + Vec::with_capacity(alias.lambda_set_variables.len()); + for typ in alias.lambda_set_variables.iter() { + if let Type::Variable(var) = typ.0 { + let fresh = var_store.fresh(); + new_lambda_set_variables.insert(fresh); + substitution.insert(var, Type::Variable(fresh)); + lambda_set_variables.push(LambdaSet(Type::Variable(fresh))); + } else { + unreachable!("at this point there should be only vars in there"); + } + } + + actual.instantiate_aliases( region, - type_got: args.len() as u8, - alias_needs: alias.type_variables.len() as u8, - }); - return; - } + aliases, + var_store, + new_lambda_set_variables, + ); - let mut actual = alias.typ.clone(); + actual.substitute(&substitution); - let mut named_args = Vec::with_capacity(args.len()); - let mut substitution = ImMap::default(); + // instantiate recursion variable! + if let Type::RecursiveTagUnion(rec_var, mut tags, mut ext) = actual { + let new_rec_var = var_store.fresh(); + substitution.clear(); + substitution.insert(rec_var, Type::Variable(new_rec_var)); - // TODO substitute further in args - for ( - Loc { - value: (lowercase, placeholder), - .. - }, - filler, - ) in alias.type_variables.iter().zip(args.iter()) - { - let mut filler = filler.clone(); - filler.instantiate_aliases(region, aliases, var_store, introduced); - named_args.push((lowercase.clone(), filler.clone())); - substitution.insert(*placeholder, filler); - } + for typ in tags.iter_mut().map(|v| v.1.iter_mut()).flatten() { + typ.substitute(&substitution); + } - // make sure hidden variables are freshly instantiated - let mut lambda_set_variables = - Vec::with_capacity(alias.lambda_set_variables.len()); - for typ in alias.lambda_set_variables.iter() { - if let Type::Variable(var) = typ.0 { - let fresh = var_store.fresh(); - introduced.insert(fresh); - substitution.insert(var, Type::Variable(fresh)); - lambda_set_variables.push(LambdaSet(Type::Variable(fresh))); - } else { - unreachable!("at this point there should be only vars in there"); + if let TypeExtension::Open(ext) = &mut ext { + ext.substitute(&substitution); + } + + actual = Type::RecursiveTagUnion(new_rec_var, tags, ext); } + let alias = Type::Alias { + symbol: *symbol, + type_arguments: named_args, + lambda_set_variables, + actual: Box::new(actual), + kind: alias.kind, + }; + + *self = alias; } - - dbg!(&actual); - - actual.instantiate_aliases(region, aliases, var_store, introduced); - - actual.substitute(&substitution); - - // instantiate recursion variable! - if let Type::RecursiveTagUnion(rec_var, mut tags, mut ext) = actual { - let new_rec_var = var_store.fresh(); - substitution.clear(); - substitution.insert(rec_var, Type::Variable(new_rec_var)); - - for typ in tags.iter_mut().map(|v| v.1.iter_mut()).flatten() { - typ.substitute(&substitution); - } - - if let TypeExtension::Open(ext) = &mut ext { - ext.substitute(&substitution); - } - - actual = Type::RecursiveTagUnion(new_rec_var, tags, ext); - } - let alias = Type::Alias { - symbol: *symbol, - type_arguments: named_args, - lambda_set_variables, - actual: Box::new(actual), - kind: alias.kind, - }; - - dbg!(&alias); - - *self = alias; - */ } else { // one of the special-cased Apply types. for x in args { From bf063d1d57dcc7e7d507be11f51057eea9df9592 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 18 Mar 2022 20:44:13 +0100 Subject: [PATCH 8/9] use all aliases that are in scope (to support imported aliases) --- compiler/can/src/annotation.rs | 6 +----- compiler/can/src/module.rs | 6 ++++-- compiler/can/src/scope.rs | 2 +- compiler/load/src/file.rs | 33 +++++++++++++++++++++++++++++++-- compiler/types/src/types.rs | 2 +- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/compiler/can/src/annotation.rs b/compiler/can/src/annotation.rs index c809ea7f05..7a486c18d2 100644 --- a/compiler/can/src/annotation.rs +++ b/compiler/can/src/annotation.rs @@ -343,12 +343,8 @@ fn can_annotation_help( return error; } - // For now, aliases of function types cannot be delayed. - // This is a limitation of the current implementation, - // and this totally should be possible in the future. - let is_import = !symbol.is_builtin() && (env.home != symbol.module_id()); let is_structural = alias.kind == AliasKind::Structural; - if !is_import && is_structural { + if is_structural { let mut type_var_to_arg = Vec::new(); for (loc_var, arg_ann) in alias.type_variables.iter().zip(args) { diff --git a/compiler/can/src/module.rs b/compiler/can/src/module.rs index 14f739a2bc..77adb88f63 100644 --- a/compiler/can/src/module.rs +++ b/compiler/can/src/module.rs @@ -500,7 +500,7 @@ pub fn canonicalize_module_defs<'a>( } } - Ok(ModuleOutput { + let output = ModuleOutput { scope, aliases, rigid_variables, @@ -511,7 +511,9 @@ pub fn canonicalize_module_defs<'a>( problems: env.problems, lookups, ident_ids: env.ident_ids, - }) + }; + + Ok(output) } (Err(runtime_error), _) => Err(runtime_error), } diff --git a/compiler/can/src/scope.rs b/compiler/can/src/scope.rs index 4863dcb5d0..76ac02ea51 100644 --- a/compiler/can/src/scope.rs +++ b/compiler/can/src/scope.rs @@ -17,7 +17,7 @@ pub struct Scope { symbols: SendMap, /// The type aliases currently in scope - aliases: SendMap, + pub aliases: SendMap, /// The current module being processed. This will be used to turn /// unqualified idents into Symbols. diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 863e1ab7ec..637ecbb3bd 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -3287,6 +3287,8 @@ fn canonicalize_and_constrain<'a>( .. } = parsed; + let before = roc_types::types::get_type_clone_count(); + let mut var_store = VarStore::default(); let canonicalized = canonicalize_module_defs( arena, @@ -3302,6 +3304,16 @@ fn canonicalize_and_constrain<'a>( &mut var_store, ); + let after = roc_types::types::get_type_clone_count(); + + log!( + "canonicalize of {:?} cloned Type {} times ({} -> {})", + module_id, + after - before, + before, + after + ); + let canonicalize_end = SystemTime::now(); module_timing.canonicalize = canonicalize_end.duration_since(canonicalize_start).unwrap(); @@ -3315,7 +3327,7 @@ fn canonicalize_and_constrain<'a>( ModuleNameEnum::App(_) => None, ModuleNameEnum::Interface(name) | ModuleNameEnum::Hosted(name) => { let docs = crate::docs::generate_module_docs( - module_output.scope, + module_output.scope.clone(), name.as_str().into(), &module_output.ident_ids, parsed_defs, @@ -3325,17 +3337,34 @@ fn canonicalize_and_constrain<'a>( } }; + let before = roc_types::types::get_type_clone_count(); + let mut constraints = Constraints::new(); + let constraint = constrain_module(&mut constraints, &module_output.declarations, module_id); + let after = roc_types::types::get_type_clone_count(); + + log!( + "constraint gen of {:?} cloned Type {} times ({} -> {})", + module_id, + after - before, + before, + after + ); + + // module_output.aliases only has aliases defined in this module + // during solving, we need all aliases that were in scope + let aliases = module_output.scope.aliases.into_iter().collect(); + let module = Module { module_id, exposed_imports: module_output.exposed_imports, exposed_symbols, referenced_values: module_output.referenced_values, referenced_types: module_output.referenced_types, - aliases: module_output.aliases, + aliases, rigid_variables: module_output.rigid_variables, }; diff --git a/compiler/types/src/types.rs b/compiler/types/src/types.rs index 7ac39697d0..e70662805e 100644 --- a/compiler/types/src/types.rs +++ b/compiler/types/src/types.rs @@ -888,7 +888,7 @@ impl Type { } DelayedAlias(AliasCommon { type_arguments, - lambda_set_variables, + lambda_set_variables: _no_aliases_in_lambda_sets, .. }) => { for (_, ta) in type_arguments { From dcd86711ecc1e855780c2be8134618cc251a229d Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 19 Mar 2022 00:27:32 +0100 Subject: [PATCH 9/9] combine aliases --- compiler/load/src/file.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 637ecbb3bd..57bc4f39aa 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -3354,9 +3354,21 @@ fn canonicalize_and_constrain<'a>( after ); - // module_output.aliases only has aliases defined in this module - // during solving, we need all aliases that were in scope - let aliases = module_output.scope.aliases.into_iter().collect(); + // scope has imported aliases, but misses aliases from inner scopes + // module_output.aliases does have those aliases, so we combine them + let mut aliases = module_output.aliases; + for (name, alias) in module_output.scope.aliases { + match aliases.entry(name) { + Occupied(_) => { + // do nothing + } + Vacant(vacant) => { + if !name.is_builtin() { + vacant.insert(alias); + } + } + } + } let module = Module { module_id,