diff --git a/Cargo.lock b/Cargo.lock index 3bdd1077d4..9da112155a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3339,6 +3339,7 @@ dependencies = [ "roc_problem", "roc_region", "roc_reporting", + "roc_solve", "roc_target", "roc_types", "roc_unify", diff --git a/crates/ast/Cargo.toml b/crates/ast/Cargo.toml index 29bc21100a..073b119d06 100644 --- a/crates/ast/Cargo.toml +++ b/crates/ast/Cargo.toml @@ -16,6 +16,7 @@ roc_parse = { path = "../compiler/parse" } roc_problem = { path = "../compiler/problem" } roc_types = { path = "../compiler/types" } roc_unify = { path = "../compiler/unify"} +roc_solve = { path = "../compiler/solve"} roc_load = { path = "../compiler/load" } roc_target = { path = "../compiler/roc_target" } roc_error_macros = { path = "../error_macros" } diff --git a/crates/compiler/types/src/builtin_aliases.rs b/crates/ast/src/builtin_aliases.rs similarity index 73% rename from crates/compiler/types/src/builtin_aliases.rs rename to crates/ast/src/builtin_aliases.rs index 3002f85783..fec813ce29 100644 --- a/crates/compiler/types/src/builtin_aliases.rs +++ b/crates/ast/src/builtin_aliases.rs @@ -1,12 +1,88 @@ -use crate::solved_types::{BuiltinAlias, SolvedType}; -use crate::subs::VarId; -use crate::types::{AliasKind, RecordField}; -use roc_collections::all::{default_hasher, MutMap}; -use roc_module::ident::TagName; +use roc_collections::all::{default_hasher, ImMap, MutMap}; +use roc_module::ident::{Lowercase, TagName}; use roc_module::symbol::Symbol; use roc_region::all::{Loc, Region}; +use roc_types::subs::{VarId, Variable}; +use roc_types::types::{AliasKind, Problem, RecordField}; use std::collections::HashMap; +#[derive(Debug, Clone)] +pub struct SolvedLambdaSet(pub SolvedType); + +/// This is a fully solved type, with no Variables remaining in it. +#[derive(Debug, Clone)] +pub enum SolvedType { + /// A function. The types of its arguments, then the type of its return value. + #[allow(unused)] + Func(Vec, Box, Box), + /// Applying a type to some arguments (e.g. Map.Map String Int) + #[allow(unused)] + Apply(Symbol, Vec), + /// A bound type variable, e.g. `a` in `(a -> a)` + #[allow(unused)] + Rigid(Lowercase), + Flex(VarId), + #[allow(unused)] + Wildcard, + /// Inline type alias, e.g. `as List a` in `[Cons a (List a), Nil] as List a` + #[allow(unused)] + Record { + fields: Vec<(Lowercase, RecordField)>, + /// The row type variable in an open record, e.g. the `r` in `{ name: Str }r`. + /// This is None if it's a closed record annotation like `{ name: Str }`. + ext: Box, + }, + #[allow(unused)] + EmptyRecord, + TagUnion(Vec<(TagName, Vec)>, Box), + #[allow(unused)] + LambdaTag(Symbol, Vec), + #[allow(unused)] + FunctionOrTagUnion(TagName, Symbol, Box), + #[allow(unused)] + RecursiveTagUnion(VarId, Vec<(TagName, Vec)>, Box), + EmptyTagUnion, + /// A type from an Invalid module + #[allow(unused)] + Erroneous(Problem), + + Alias( + Symbol, + Vec, + Vec, + Box, + AliasKind, + ), + + #[allow(unused)] + HostExposedAlias { + name: Symbol, + arguments: Vec, + lambda_set_variables: Vec, + actual_var: VarId, + actual: Box, + }, + + /// A type error + #[allow(unused)] + Error, +} + +#[derive(Clone, Debug)] +pub struct BuiltinAlias { + pub region: Region, + pub vars: Vec>, + pub typ: SolvedType, + pub kind: AliasKind, +} + +#[derive(Debug, Clone, Default)] +pub struct FreeVars { + pub named_vars: ImMap, + pub unnamed_vars: ImMap, + pub wildcards: Vec, +} + const NUM_BUILTIN_IMPORTS: usize = 8; /// These can be shared between definitions, they will get instantiated when converted to Type @@ -411,235 +487,66 @@ fn floatingpoint_alias_content(range: SolvedType) -> SolvedType { range } -// FRAC - -#[inline(always)] -pub fn frac_type(range: SolvedType) -> SolvedType { - SolvedType::Alias( - Symbol::NUM_FRAC, - vec![(range.clone())], - vec![], - Box::new(frac_alias_content(range)), - AliasKind::Structural, - ) -} - #[inline(always)] fn frac_alias_content(range: SolvedType) -> SolvedType { num_type(floatingpoint_type(range)) } -// F64 - -#[inline(always)] -pub fn f64_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_F64, - vec![], - vec![], - Box::new(f64_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn f64_alias_content() -> SolvedType { frac_alias_content(binary64_type()) } -// F32 - -#[inline(always)] -pub fn f32_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_F32, - vec![], - vec![], - Box::new(f32_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn f32_alias_content() -> SolvedType { frac_alias_content(binary32_type()) } -// Nat - -#[inline(always)] -pub fn nat_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_NAT, - vec![], - vec![], - Box::new(nat_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn nat_alias_content() -> SolvedType { int_alias_content(natural_type()) } -// I128 - -#[inline(always)] -pub fn i128_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_I128, - vec![], - vec![], - Box::new(i128_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn i128_alias_content() -> SolvedType { int_alias_content(signed128_type()) } -// I128 - -#[inline(always)] -pub fn u128_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_U128, - vec![], - vec![], - Box::new(u128_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn u128_alias_content() -> SolvedType { int_alias_content(unsigned128_type()) } -// U64 - -#[inline(always)] -pub fn u64_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_U64, - vec![], - vec![], - Box::new(u64_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn u64_alias_content() -> SolvedType { int_alias_content(unsigned64_type()) } -// I64 - -#[inline(always)] -pub fn i64_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_I64, - vec![], - vec![], - Box::new(i64_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn i64_alias_content() -> SolvedType { int_alias_content(signed64_type()) } -// U32 - -#[inline(always)] -pub fn u32_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_U32, - vec![], - vec![], - Box::new(u32_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn u32_alias_content() -> SolvedType { int_alias_content(unsigned32_type()) } -// I32 - -#[inline(always)] -pub fn i32_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_I32, - vec![], - vec![], - Box::new(i32_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn i32_alias_content() -> SolvedType { int_alias_content(signed32_type()) } -// U16 - -#[inline(always)] -pub fn u16_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_U16, - vec![], - vec![], - Box::new(u16_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn u16_alias_content() -> SolvedType { int_alias_content(unsigned16_type()) } -// I16 - -#[inline(always)] -pub fn i16_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_I16, - vec![], - vec![], - Box::new(i16_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn i16_alias_content() -> SolvedType { int_alias_content(signed16_type()) } -// U8 - -#[inline(always)] -pub fn u8_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_U8, - vec![], - vec![], - Box::new(u8_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn u8_alias_content() -> SolvedType { int_alias_content(unsigned8_type()) @@ -647,35 +554,11 @@ fn u8_alias_content() -> SolvedType { // I8 -#[inline(always)] -pub fn i8_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_I8, - vec![], - vec![], - Box::new(i8_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn i8_alias_content() -> SolvedType { int_alias_content(signed8_type()) } -// INT - -#[inline(always)] -pub fn int_type(range: SolvedType) -> SolvedType { - SolvedType::Alias( - Symbol::NUM_INT, - vec![(range.clone())], - vec![], - Box::new(int_alias_content(range)), - AliasKind::Structural, - ) -} - #[inline(always)] fn int_alias_content(range: SolvedType) -> SolvedType { num_type(integer_type(range)) @@ -912,19 +795,6 @@ fn decimal_alias_content() -> SolvedType { SolvedType::EmptyTagUnion } -// Dec - -#[inline(always)] -pub fn dec_type() -> SolvedType { - SolvedType::Alias( - Symbol::NUM_DEC, - vec![], - vec![], - Box::new(dec_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] fn dec_alias_content() -> SolvedType { frac_alias_content(decimal_type()) @@ -941,17 +811,6 @@ pub fn decimal_type() -> SolvedType { ) } -#[inline(always)] -pub fn bool_type() -> SolvedType { - SolvedType::Alias( - Symbol::BOOL_BOOL, - vec![], - vec![], - Box::new(bool_alias_content()), - AliasKind::Structural, - ) -} - fn bool_alias_content() -> SolvedType { SolvedType::TagUnion( vec![ @@ -962,92 +821,6 @@ fn bool_alias_content() -> SolvedType { ) } -#[inline(always)] -pub fn ordering_type() -> SolvedType { - // [LT, EQ, GT] - SolvedType::TagUnion( - vec![ - (TagName("EQ".into()), vec![]), - (TagName("GT".into()), vec![]), - (TagName("LT".into()), vec![]), - ], - Box::new(SolvedType::EmptyTagUnion), - ) -} - -#[inline(always)] -pub fn result_type(a: SolvedType, e: SolvedType) -> SolvedType { - SolvedType::Alias( - Symbol::RESULT_RESULT, - vec![a.clone(), e.clone()], - vec![], - Box::new(result_alias_content(a, e)), - AliasKind::Structural, - ) -} - -#[inline(always)] -pub fn box_type(a: SolvedType) -> SolvedType { - SolvedType::Apply(Symbol::BOX_BOX_TYPE, vec![a]) -} - -#[inline(always)] -fn result_alias_content(a: SolvedType, e: SolvedType) -> SolvedType { - SolvedType::TagUnion( - vec![ - (TagName("Err".into()), vec![e]), - (TagName("Ok".into()), vec![a]), - ], - Box::new(SolvedType::EmptyTagUnion), - ) -} - -#[inline(always)] -pub fn list_type(a: SolvedType) -> SolvedType { - SolvedType::Apply(Symbol::LIST_LIST, vec![a]) -} - -#[inline(always)] -pub fn str_type() -> SolvedType { - SolvedType::Apply(Symbol::STR_STR, Vec::new()) -} - -#[inline(always)] -pub fn str_utf8_problem_type() -> SolvedType { - SolvedType::Alias( - Symbol::STR_UT8_PROBLEM, - vec![], - vec![], - Box::new(str_utf8_problem_alias_content()), - AliasKind::Structural, - ) -} - -#[inline(always)] -pub fn str_utf8_problem_alias_content() -> SolvedType { - SolvedType::Record { - fields: vec![ - ("byteIndex".into(), RecordField::Required(nat_type())), - ( - "problem".into(), - RecordField::Required(str_utf8_byte_problem_type()), - ), - ], - ext: Box::new(SolvedType::EmptyRecord), - } -} - -#[inline(always)] -pub fn str_utf8_byte_problem_type() -> SolvedType { - SolvedType::Alias( - Symbol::STR_UT8_BYTE_PROBLEM, - vec![], - vec![], - Box::new(str_utf8_byte_problem_alias_content()), - AliasKind::Structural, - ) -} - #[inline(always)] pub fn str_utf8_byte_problem_alias_content() -> SolvedType { // 1. This must have the same values as the Zig struct Utf8ByteProblem in src/str.zig @@ -1066,13 +839,3 @@ pub fn str_utf8_byte_problem_alias_content() -> SolvedType { Box::new(SolvedType::EmptyTagUnion), ) } - -#[inline(always)] -pub fn set_type(a: SolvedType) -> SolvedType { - SolvedType::Apply(Symbol::SET_SET, vec![a]) -} - -#[inline(always)] -pub fn dict_type(key: SolvedType, value: SolvedType) -> SolvedType { - SolvedType::Apply(Symbol::DICT_DICT, vec![key, value]) -} diff --git a/crates/ast/src/constrain.rs b/crates/ast/src/constrain.rs index da5d6e543a..ec381f4032 100644 --- a/crates/ast/src/constrain.rs +++ b/crates/ast/src/constrain.rs @@ -1937,9 +1937,9 @@ pub mod test_constrain { }; use roc_parse::parser::{SourceError, SyntaxError}; use roc_region::all::Region; + use roc_solve::module::Solved; use roc_types::{ pretty_print::{name_and_print_var, DebugPrint}, - solved_types::Solved, subs::{Subs, VarStore, Variable}, }; diff --git a/crates/ast/src/lang/scope.rs b/crates/ast/src/lang/scope.rs index c8e203da4c..7490df6fe1 100644 --- a/crates/ast/src/lang/scope.rs +++ b/crates/ast/src/lang/scope.rs @@ -5,6 +5,7 @@ use std::fmt; use crate::ast_error::ASTResult; +use crate::builtin_aliases::{self, BuiltinAlias, FreeVars, SolvedType}; use crate::mem_pool::pool::Pool; use crate::mem_pool::pool_str::PoolStr; use crate::mem_pool::pool_vec::PoolVec; @@ -17,11 +18,7 @@ use roc_module::symbol::{ }; use roc_problem::can::RuntimeError; use roc_region::all::{Loc, Region}; -use roc_types::{ - builtin_aliases, - solved_types::{BuiltinAlias, FreeVars, SolvedType}, - subs::{VarId, VarStore, Variable}, -}; +use roc_types::subs::{VarId, VarStore, Variable}; use super::core::types::{Alias, Type2, TypeId}; use super::env::Env; diff --git a/crates/ast/src/lib.rs b/crates/ast/src/lib.rs index 092b86154e..610ed3442b 100644 --- a/crates/ast/src/lib.rs +++ b/crates/ast/src/lib.rs @@ -1,4 +1,5 @@ pub mod ast_error; +mod builtin_aliases; mod canonicalization; pub mod constrain; pub mod lang; diff --git a/crates/ast/src/solve_type.rs b/crates/ast/src/solve_type.rs index dc9950106d..10db23ea45 100644 --- a/crates/ast/src/solve_type.rs +++ b/crates/ast/src/solve_type.rs @@ -7,7 +7,7 @@ use roc_error_macros::internal_error; use roc_module::ident::TagName; use roc_module::symbol::Symbol; use roc_region::all::{Loc, Region}; -use roc_types::solved_types::Solved; +use roc_solve::module::Solved; use roc_types::subs::{ self, AliasVariables, Content, Descriptor, FlatType, Mark, OptVariable, Rank, RecordFields, Subs, SubsSlice, UnionLambdas, UnionTags, Variable, VariableSubsSlice, diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index 8bd3c31cb1..19cd39a1b2 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -41,10 +41,9 @@ use roc_parse::module::module_defs; use roc_parse::parser::{FileError, Parser, SyntaxError}; use roc_region::all::{LineInfo, Loc, Region}; use roc_reporting::report::RenderTarget; -use roc_solve::module::SolvedModule; +use roc_solve::module::{Solved, SolvedModule}; use roc_solve::solve; use roc_target::TargetInfo; -use roc_types::solved_types::Solved; use roc_types::subs::{ExposedTypesStorageSubs, Subs, VarStore, Variable}; use roc_types::types::{Alias, AliasKind}; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -4875,7 +4874,7 @@ fn build_pending_specializations<'a>( Msg::FoundSpecializations { module_id: home, - solved_subs: roc_types::solved_types::Solved(subs), + solved_subs: Solved(subs), ident_ids, layout_cache, procs_base, diff --git a/crates/compiler/solve/src/module.rs b/crates/compiler/solve/src/module.rs index 0267d542a1..7aab8fba67 100644 --- a/crates/compiler/solve/src/module.rs +++ b/crates/compiler/solve/src/module.rs @@ -8,10 +8,28 @@ use roc_collections::VecMap; use roc_derive_key::GlobalDerivedSymbols; use roc_error_macros::internal_error; use roc_module::symbol::Symbol; -use roc_types::solved_types::Solved; use roc_types::subs::{Content, ExposedTypesStorageSubs, FlatType, StorageSubs, Subs, Variable}; use roc_types::types::Alias; +/// A marker that a given Subs has been solved. +/// The only way to obtain a Solved is by running the solver on it. +#[derive(Clone, Debug)] +pub struct Solved(pub T); + +impl Solved { + pub fn inner(&self) -> &'_ T { + &self.0 + } + + pub fn inner_mut(&mut self) -> &'_ mut T { + &mut self.0 + } + + pub fn into_inner(self) -> T { + self.0 + } +} + #[derive(Debug)] pub struct SolvedModule { pub problems: Vec, diff --git a/crates/compiler/solve/src/solve.rs b/crates/compiler/solve/src/solve.rs index 808a95034e..bd2f6873f4 100644 --- a/crates/compiler/solve/src/solve.rs +++ b/crates/compiler/solve/src/solve.rs @@ -2,6 +2,7 @@ use crate::ability::{ resolve_ability_specialization, type_implementing_specialization, AbilityImplError, DeferredObligations, PendingDerivesTable, RequestedDeriveKey, Resolved, Unfulfilled, }; +use crate::module::Solved; use bumpalo::Bump; use roc_can::abilities::{AbilitiesStore, MemberSpecialization}; use roc_can::constraint::Constraint::{self, *}; @@ -18,7 +19,6 @@ use roc_module::ident::TagName; use roc_module::symbol::{ModuleId, Symbol}; use roc_problem::can::CycleEntry; use roc_region::all::{Loc, Region}; -use roc_types::solved_types::Solved; use roc_types::subs::{ self, AliasVariables, Content, Descriptor, FlatType, GetSubsSlice, LambdaSet, Mark, OptVariable, Rank, RecordFields, Subs, SubsIndex, SubsSlice, UlsOfVar, UnionLabels, diff --git a/crates/compiler/types/src/lib.rs b/crates/compiler/types/src/lib.rs index 0846e058aa..09e98b7d82 100644 --- a/crates/compiler/types/src/lib.rs +++ b/crates/compiler/types/src/lib.rs @@ -1,10 +1,8 @@ #![warn(clippy::dbg_macro)] // See github.com/rtfeldman/roc/issues/800 for discussion of the large_enum_variant check. #![allow(clippy::large_enum_variant)] -pub mod builtin_aliases; pub mod num; pub mod pretty_print; -pub mod solved_types; pub mod subs; pub mod types; mod unification_table; diff --git a/crates/compiler/types/src/solved_types.rs b/crates/compiler/types/src/solved_types.rs deleted file mode 100644 index e41554da66..0000000000 --- a/crates/compiler/types/src/solved_types.rs +++ /dev/null @@ -1,90 +0,0 @@ -use crate::subs::{VarId, Variable}; -use crate::types::{AliasKind, Problem, RecordField}; -use roc_collections::all::ImMap; -use roc_module::ident::{Lowercase, TagName}; -use roc_module::symbol::Symbol; -use roc_region::all::{Loc, Region}; - -/// A marker that a given Subs has been solved. -/// The only way to obtain a Solved is by running the solver on it. -#[derive(Clone, Debug)] -pub struct Solved(pub T); - -impl Solved { - pub fn inner(&self) -> &'_ T { - &self.0 - } - - pub fn inner_mut(&mut self) -> &'_ mut T { - &mut self.0 - } - - pub fn into_inner(self) -> T { - self.0 - } -} - -#[derive(Debug, Clone)] -pub struct SolvedLambdaSet(pub SolvedType); - -/// This is a fully solved type, with no Variables remaining in it. -#[derive(Debug, Clone)] -pub enum SolvedType { - /// A function. The types of its arguments, then the type of its return value. - Func(Vec, Box, Box), - /// Applying a type to some arguments (e.g. Map.Map String Int) - Apply(Symbol, Vec), - /// A bound type variable, e.g. `a` in `(a -> a)` - Rigid(Lowercase), - Flex(VarId), - Wildcard, - /// Inline type alias, e.g. `as List a` in `[Cons a (List a), Nil] as List a` - Record { - fields: Vec<(Lowercase, RecordField)>, - /// The row type variable in an open record, e.g. the `r` in `{ name: Str }r`. - /// This is None if it's a closed record annotation like `{ name: Str }`. - ext: Box, - }, - EmptyRecord, - TagUnion(Vec<(TagName, Vec)>, Box), - LambdaTag(Symbol, Vec), - FunctionOrTagUnion(TagName, Symbol, Box), - RecursiveTagUnion(VarId, Vec<(TagName, Vec)>, Box), - EmptyTagUnion, - /// A type from an Invalid module - Erroneous(Problem), - - Alias( - Symbol, - Vec, - Vec, - Box, - AliasKind, - ), - - HostExposedAlias { - name: Symbol, - arguments: Vec, - lambda_set_variables: Vec, - actual_var: VarId, - actual: Box, - }, - - /// A type error - Error, -} - -#[derive(Clone, Debug)] -pub struct BuiltinAlias { - pub region: Region, - pub vars: Vec>, - pub typ: SolvedType, - pub kind: AliasKind, -} - -#[derive(Debug, Clone, Default)] -pub struct FreeVars { - pub named_vars: ImMap, - pub unnamed_vars: ImMap, - pub wildcards: Vec, -} diff --git a/crates/editor/src/editor/mvc/ed_update.rs b/crates/editor/src/editor/mvc/ed_update.rs index 4f731ed0f8..6bae9d3a07 100644 --- a/crates/editor/src/editor/mvc/ed_update.rs +++ b/crates/editor/src/editor/mvc/ed_update.rs @@ -59,9 +59,9 @@ use roc_collections::all::MutMap; use roc_module::ident::Lowercase; use roc_module::symbol::Symbol; use roc_region::all::Region; +use roc_solve::module::Solved; use roc_types::pretty_print::name_and_print_var; use roc_types::pretty_print::DebugPrint; -use roc_types::solved_types::Solved; use roc_types::subs::{Subs, VarStore, Variable}; use snafu::OptionExt; use threadpool::ThreadPool;