diff --git a/compiler/can/src/annotation.rs b/compiler/can/src/annotation.rs index 45f42692e4..8e49713914 100644 --- a/compiler/can/src/annotation.rs +++ b/compiler/can/src/annotation.rs @@ -1045,26 +1045,35 @@ pub fn instantiate_and_freshen_alias_type( pub fn freshen_opaque_def( var_store: &mut VarStore, opaque: &Alias, -) -> (Vec<(Lowercase, Type)>, Vec, Type) { +) -> (Vec, Vec, Type) { debug_assert!(opaque.kind == AliasKind::Opaque); - let fresh_arguments = opaque + let fresh_variables: Vec = opaque .type_variables .iter() - .map(|_| Type::Variable(var_store.fresh())) + .map(|_| var_store.fresh()) .collect(); - // TODO this gets ignored; is that a problem + let fresh_type_arguments = fresh_variables + .iter() + .copied() + .map(Type::Variable) + .collect(); + + // NB: We don't introduce the fresh variables here, we introduce them during constraint gen. + // NB: If there are bugs, check whether this is a problem! let mut introduced_variables = IntroducedVariables::default(); - instantiate_and_freshen_alias_type( + let (_fresh_type_arguments, fresh_lambda_set, fresh_type) = instantiate_and_freshen_alias_type( var_store, &mut introduced_variables, &opaque.type_variables, - fresh_arguments, + fresh_type_arguments, &opaque.lambda_set_variables, opaque.typ.clone(), - ) + ); + + (fresh_variables, fresh_lambda_set, fresh_type) } fn insertion_sort_by(arr: &mut [T], mut compare: F) diff --git a/compiler/can/src/effect_module.rs b/compiler/can/src/effect_module.rs index b302b64e71..b416483dc2 100644 --- a/compiler/can/src/effect_module.rs +++ b/compiler/can/src/effect_module.rs @@ -5,7 +5,7 @@ use crate::pattern::Pattern; use crate::scope::Scope; use roc_collections::{SendMap, VecSet}; use roc_module::called_via::CalledVia; -use roc_module::ident::{Lowercase, TagName}; +use roc_module::ident::TagName; use roc_module::symbol::Symbol; use roc_region::all::{Loc, Region}; use roc_types::subs::{ExhaustiveMark, RedundantMark, VarStore, Variable}; @@ -1466,7 +1466,7 @@ fn build_effect_opaque( fn build_fresh_opaque_variables( var_store: &mut VarStore, -) -> (Box, Vec<(Lowercase, Type)>, Vec) { +) -> (Box, Vec, Vec) { let closure_var = var_store.fresh(); // NB: if there are bugs, check whether not introducing variables is a problem! @@ -1478,7 +1478,7 @@ fn build_fresh_opaque_variables( Box::new(Type::Variable(closure_var)), Box::new(Type::Variable(a_var)), ); - let type_arguments = vec![("a".into(), Type::Variable(a_var))]; + let type_arguments = vec![a_var]; let lambda_set_variables = vec![roc_types::types::LambdaSet(Type::Variable(closure_var))]; (Box::new(actual), type_arguments, lambda_set_variables) diff --git a/compiler/can/src/expr.rs b/compiler/can/src/expr.rs index d9d844291c..4138ab07ae 100644 --- a/compiler/can/src/expr.rs +++ b/compiler/can/src/expr.rs @@ -190,7 +190,7 @@ pub enum Expr { // for the expression from the opaque definition. `type_arguments` is something like // [(n, fresh1)], and `specialized_def_type` becomes "[ Id U64 fresh1 ]". specialized_def_type: Box, - type_arguments: Vec<(Lowercase, Type)>, + type_arguments: Vec, lambda_set_variables: Vec, }, diff --git a/compiler/can/src/pattern.rs b/compiler/can/src/pattern.rs index f2ca57a239..2318d8b115 100644 --- a/compiler/can/src/pattern.rs +++ b/compiler/can/src/pattern.rs @@ -47,7 +47,7 @@ pub enum Pattern { // for the expression from the opaque definition. `type_arguments` is something like // [(n, fresh1)], and `specialized_def_type` becomes "[ Id U64 fresh1 ]". specialized_def_type: Box, - type_arguments: Vec<(Lowercase, Type)>, + type_arguments: Vec, lambda_set_variables: Vec, }, RecordDestructure { diff --git a/compiler/constrain/src/expr.rs b/compiler/constrain/src/expr.rs index 32d449f7b0..364930ef14 100644 --- a/compiler/constrain/src/expr.rs +++ b/compiler/constrain/src/expr.rs @@ -1022,7 +1022,10 @@ pub fn constrain_expr( let opaque_type = Type::Alias { symbol: *name, - type_arguments: type_arguments.clone(), + type_arguments: type_arguments + .iter() + .map(|v| ("".into(), Type::Variable(*v))) + .collect(), lambda_set_variables: lambda_set_variables.clone(), actual: Box::new(arg_type.clone()), kind: AliasKind::Opaque, @@ -1059,9 +1062,7 @@ pub fn constrain_expr( let mut vars = vec![*arg_var, *opaque_var]; // Also add the fresh variables we created for the type argument and lambda sets - vars.extend(type_arguments.iter().map(|(_, t)| { - t.expect_variable("all type arguments should be fresh variables here") - })); + vars.extend(type_arguments); vars.extend(lambda_set_variables.iter().map(|v| { v.0.expect_variable("all lambda sets should be fresh variables here") })); diff --git a/compiler/constrain/src/pattern.rs b/compiler/constrain/src/pattern.rs index 9f6cc6c468..26c4d1826a 100644 --- a/compiler/constrain/src/pattern.rs +++ b/compiler/constrain/src/pattern.rs @@ -514,7 +514,10 @@ pub fn constrain_pattern( let opaque_type = Type::Alias { symbol: *opaque, - type_arguments: type_arguments.clone(), + type_arguments: type_arguments + .iter() + .map(|v| ("".into(), Type::Variable(*v))) + .collect(), lambda_set_variables: lambda_set_variables.clone(), actual: Box::new(arg_pattern_type.clone()), kind: AliasKind::Opaque, @@ -571,9 +574,7 @@ pub fn constrain_pattern( .vars .extend_from_slice(&[*arg_pattern_var, *whole_var]); // Also add the fresh variables we created for the type argument and lambda sets - state.vars.extend(type_arguments.iter().map(|(_, t)| { - t.expect_variable("all type arguments should be fresh variables here") - })); + state.vars.extend(type_arguments); state.vars.extend(lambda_set_variables.iter().map(|v| { v.0.expect_variable("all lambda sets should be fresh variables here") }));