diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 66d697d976..7d10a7a86c 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -4713,7 +4713,7 @@ fn canonicalize_and_constrain<'a>( &symbols_from_requires, &mut var_store, ); - let types = Types::new(); + let mut types = Types::new(); // _after has an underscore because it's unused in --release builds let _after = roc_types::types::get_type_clone_count(); diff --git a/crates/compiler/solve/src/ability.rs b/crates/compiler/solve/src/ability.rs index 41ec8267aa..e117298b4c 100644 --- a/crates/compiler/solve/src/ability.rs +++ b/crates/compiler/solve/src/ability.rs @@ -75,6 +75,7 @@ impl PendingDerivesTable { let derive_key = RequestedDeriveKey { opaque, ability }; // Neither rank nor pools should matter here. + let typ = types.from_old_type(&typ); let opaque_var = type_to_var( subs, Rank::toplevel(), @@ -84,7 +85,7 @@ impl PendingDerivesTable { &mut Pools::default(), types, aliases, - &typ, + typ, ); let real_var = match subs.get_content_without_compacting(opaque_var) { Content::Alias(_, _, real_var, AliasKind::Opaque) => real_var, diff --git a/crates/compiler/solve/src/solve.rs b/crates/compiler/solve/src/solve.rs index 179263aadd..39042aa3ff 100644 --- a/crates/compiler/solve/src/solve.rs +++ b/crates/compiler/solve/src/solve.rs @@ -1347,10 +1347,10 @@ fn solve( .map(|v| Type::Variable(*v)) .collect(); - let tag_ty = Type::TagUnion( + let tag_ty = can_types.from_old_type(&Type::TagUnion( vec![(tag_name.clone(), payload_types)], TypeExtension::Closed, - ); + )); let includes = type_to_var( subs, rank, @@ -1360,7 +1360,7 @@ fn solve( pools, &mut can_types, aliases, - &tag_ty, + tag_ty, ); match unify( @@ -2265,7 +2265,7 @@ fn type_cell_to_var( aliases: &mut Aliases, typ_cell: &Cell>, ) -> Variable { - let typ = typ_cell.replace(Type::EmptyTagUnion); + let typ = typ_cell.get(); let var = type_to_var( subs, rank, @@ -2275,9 +2275,12 @@ fn type_cell_to_var( pools, types, aliases, - &typ, + typ, ); - typ_cell.replace(Type::Variable(var)); + unsafe { + types.set_variable(typ, var); + } + var } @@ -2290,13 +2293,12 @@ pub(crate) fn type_to_var( pools: &mut Pools, types: &mut Types, aliases: &mut Aliases, - typ: &Type, + typ: Index, ) -> Variable { - if let Type::Variable(var) = typ { - *var + if let TypeTag::Variable(var) = types[typ] { + var } else { let mut arena = take_scratchpad(); - let typ = types.from_old_type(typ); let var = type_to_variable( subs, diff --git a/crates/compiler/test_derive/src/util.rs b/crates/compiler/test_derive/src/util.rs index 8c011f4a84..92fbcec7f6 100644 --- a/crates/compiler/test_derive/src/util.rs +++ b/crates/compiler/test_derive/src/util.rs @@ -27,6 +27,7 @@ use roc_reporting::report::{type_problem, RocDocAllocator}; use roc_types::{ pretty_print::{name_and_print_var, DebugPrint}, subs::{ExposedTypesStorageSubs, Subs, Variable}, + types::Types, }; const DERIVED_MODULE: ModuleId = ModuleId::DERIVED_SYNTH; @@ -343,11 +344,12 @@ fn check_derived_typechecks_and_golden( check_golden: impl Fn(&str), ) { // constrain the derived + let mut types = Types::new(); let mut constraints = Constraints::new(); let def_var = derived_def.expr_var; let mut decls = Declarations::new(); decls.push_def(derived_def); - let constr = constrain_decls(&mut constraints, test_module, &decls); + let constr = constrain_decls(&mut types, &mut constraints, test_module, &decls); // the derived implementation on stuff from the builtin module, so // - we need to add those dependencies as imported on the constraint @@ -394,7 +396,7 @@ fn check_derived_typechecks_and_golden( ); let (mut solved_subs, _, problems, _) = roc_solve::module::run_solve( test_module, - Default::default(), + types, &constraints, constr, RigidVariables::default(), diff --git a/crates/compiler/types/src/types.rs b/crates/compiler/types/src/types.rs index 0c52ee4a42..33ce9ff995 100644 --- a/crates/compiler/types/src/types.rs +++ b/crates/compiler/types/src/types.rs @@ -586,6 +586,13 @@ impl Types { (tags, payload_slices) } + /// # Safety + /// + /// May only be called if `var` is known to represent the type at `index`. + pub unsafe fn set_variable(&mut self, index: Index, var: Variable) { + self.tags[index.index()] = TypeTag::Variable(var); + } + fn reserve_type_tags(&mut self, length: usize) -> Slice { use std::iter::repeat; diff --git a/crates/reporting/tests/helpers/mod.rs b/crates/reporting/tests/helpers/mod.rs index 195a27b6b3..b65a928648 100644 --- a/crates/reporting/tests/helpers/mod.rs +++ b/crates/reporting/tests/helpers/mod.rs @@ -143,11 +143,12 @@ pub fn can_expr_with<'a>( } }; + let mut types = Types::new(); let mut constraints = Constraints::new(); let mut var_store = VarStore::default(); let var = var_store.fresh(); - let var_index = constraints.push_type(Type::Variable(var)); + let var_index = constraints.push_variable(var); let expected = constraints.push_expected_type(Expected::NoExpectation(var_index)); let mut module_ids = ModuleIds::default(); @@ -176,6 +177,7 @@ pub fn can_expr_with<'a>( ); let constraint = constrain_expr( + &mut types, &mut constraints, &mut roc_constrain::expr::Env { rigids: MutMap::default(), @@ -205,7 +207,7 @@ pub fn can_expr_with<'a>( var, constraint, constraints, - types: Default::default(), + types, }) }