diff --git a/Cargo.lock b/Cargo.lock index 052d61c52a..3247f2ce5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -886,7 +886,9 @@ dependencies = [ "roc_parse", "roc_problem", "roc_region", + "roc_solve", "roc_types", + "roc_unify", "roc_uniqueness", "target-lexicon", "tokio", @@ -1009,6 +1011,23 @@ dependencies = [ name = "roc_region" version = "0.1.0" +[[package]] +name = "roc_solve" +version = "0.1.0" +dependencies = [ + "indoc", + "maplit", + "pretty_assertions", + "quickcheck", + "quickcheck_macros", + "roc_can", + "roc_collections", + "roc_module", + "roc_region", + "roc_types", + "roc_unify", +] + [[package]] name = "roc_types" version = "0.1.0" @@ -1027,6 +1046,20 @@ dependencies = [ "ven_ena", ] +[[package]] +name = "roc_unify" +version = "0.1.0" +dependencies = [ + "indoc", + "maplit", + "pretty_assertions", + "quickcheck", + "quickcheck_macros", + "roc_collections", + "roc_module", + "roc_types", +] + [[package]] name = "roc_uniqueness" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 57b9974f20..1ad1ed0b7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ members = [ "compiler/uniqueness", "compiler/builtins", "compiler/constrain", + "compiler/unify", + "compiler/solve", "vendor/ena", "vendor/pathfinding" ] diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 97097adc61..aa1d5c7868 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -15,6 +15,8 @@ roc_can = { path = "./can" } roc_builtins = { path = "./builtins" } roc_constrain = { path = "./constrain" } roc_uniqueness = { path = "./uniqueness" } +roc_unify = { path = "./unify" } +roc_solve = { path = "./solve" } log = "0.4.8" petgraph = { version = "0.4.5", optional = true } im = "14" # im and im-rc should always have the same version! diff --git a/compiler/solve/Cargo.toml b/compiler/solve/Cargo.toml new file mode 100644 index 0000000000..09e54217e8 --- /dev/null +++ b/compiler/solve/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "roc_solve" +version = "0.1.0" +authors = ["Richard Feldman "] +edition = "2018" + +[dependencies] +roc_collections = { path = "../collections" } +roc_region = { path = "../region" } +roc_module = { path = "../module" } +roc_types = { path = "../types" } +roc_can = { path = "../can" } +roc_unify = { path = "../unify" } + +[dev-dependencies] +pretty_assertions = "0.5.1 " +maplit = "1.0.1" +indoc = "0.3.3" +quickcheck = "0.8" +quickcheck_macros = "0.8" diff --git a/compiler/solve/src/lib.rs b/compiler/solve/src/lib.rs new file mode 100644 index 0000000000..16a989c482 --- /dev/null +++ b/compiler/solve/src/lib.rs @@ -0,0 +1,14 @@ +#![warn(clippy::all, clippy::dbg_macro)] +// I'm skeptical that clippy:large_enum_variant is a good lint to have globally enabled. +// +// It warns about a performance problem where the only quick remediation is +// to allocate more on the heap, which has lots of tradeoffs - including making it +// long-term unclear which allocations *need* to happen for compilation's sake +// (e.g. recursive structures) versus those which were only added to appease clippy. +// +// Effectively optimizing data struture memory layout isn't a quick fix, +// and encouraging shortcuts here creates bad incentives. I would rather temporarily +// re-enable this when working on performance optimizations than have it block PRs. +#![allow(clippy::large_enum_variant)] + +pub mod solve; diff --git a/compiler/src/solve.rs b/compiler/solve/src/solve.rs similarity index 99% rename from compiler/src/solve.rs rename to compiler/solve/src/solve.rs index df00fa3473..3c3f96fe6c 100644 --- a/compiler/src/solve.rs +++ b/compiler/solve/src/solve.rs @@ -1,4 +1,3 @@ -use crate::unify::{unify, Unified}; use roc_can::constraint::Constraint::{self, *}; use roc_collections::all::{ImMap, MutMap, SendMap}; use roc_module::ident::TagName; @@ -9,6 +8,7 @@ use roc_types::solved_types::{Solved, SolvedType}; use roc_types::subs::{Content, Descriptor, FlatType, Mark, OptVariable, Rank, Subs, Variable}; use roc_types::types::Type::{self, *}; use roc_types::types::{Alias, Problem}; +use roc_unify::unify::{unify, Unified}; // Type checking system adapted from Elm by Evan Czaplicki, BSD-3-Clause Licensed // https://github.com/elm/compiler diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 7e7e1549ce..6405af3d2b 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -22,5 +22,3 @@ pub mod load; pub mod mono; pub mod pretty_print_types; pub mod reporting; -pub mod solve; -pub mod unify; diff --git a/compiler/src/load/mod.rs b/compiler/src/load/mod.rs index 03bfa0c1b5..ba1fe44954 100644 --- a/compiler/src/load/mod.rs +++ b/compiler/src/load/mod.rs @@ -1,4 +1,3 @@ -use crate::solve::{self, ExposedModuleTypes, SubsByModule}; use bumpalo::Bump; use roc_builtins::all::Mode; use roc_builtins::all::StdLib; @@ -17,6 +16,7 @@ use roc_parse::ast::{self, Attempting, ExposesEntry, ImportsEntry, InterfaceHead use roc_parse::module::module_defs; use roc_parse::parser::{Fail, Parser, State}; use roc_region::all::{Located, Region}; +use roc_solve::solve::{self, ExposedModuleTypes, SubsByModule}; use roc_types::solved_types::{BuiltinAlias, Solved, SolvedType}; use roc_types::subs::{Subs, VarStore, Variable}; use roc_types::types::{self, Alias}; diff --git a/compiler/src/pretty_print_types.rs b/compiler/src/pretty_print_types.rs index d4f9168746..0d99bff194 100644 --- a/compiler/src/pretty_print_types.rs +++ b/compiler/src/pretty_print_types.rs @@ -345,8 +345,7 @@ fn write_flat_type( EmptyTagUnion => buf.push_str(EMPTY_TAG_UNION), Func(args, ret) => write_fn(env, args, ret, subs, buf, parens), Record(fields, ext_var) => { - use crate::unify::gather_fields; - use crate::unify::RecordStructure; + use roc_unify::unify::{gather_fields, RecordStructure}; // If the `ext` has concrete fields (e.g. { foo : Int}{ bar : Bool }), merge them let RecordStructure { fields, ext } = gather_fields(subs, fields, ext_var); diff --git a/compiler/tests/helpers/mod.rs b/compiler/tests/helpers/mod.rs index 32f6130303..586aad10e5 100644 --- a/compiler/tests/helpers/mod.rs +++ b/compiler/tests/helpers/mod.rs @@ -1,7 +1,6 @@ extern crate bumpalo; use self::bumpalo::Bump; -use roc::solve; use roc::unique_builtins; use roc_can::constraint::Constraint; use roc_can::env::Env; @@ -20,6 +19,7 @@ use roc_parse::blankspace::space0_before; use roc_parse::parser::{loc, Fail, Parser, State}; use roc_problem::can::Problem; use roc_region::all::{Located, Region}; +use roc_solve::solve; use roc_types::subs::{Content, Subs, VarStore, Variable}; use roc_types::types::Type; use std::hash::Hash; diff --git a/compiler/tests/test_load.rs b/compiler/tests/test_load.rs index 2f0835b88a..8aa3041d9d 100644 --- a/compiler/tests/test_load.rs +++ b/compiler/tests/test_load.rs @@ -18,11 +18,11 @@ mod test_load { use inlinable_string::InlinableString; use roc::load::{load, LoadedModule}; use roc::pretty_print_types::{content_to_string, name_all_type_vars}; - use roc::solve::SubsByModule; use roc_can::def::Declaration::*; use roc_can::def::Def; use roc_collections::all::MutMap; use roc_module::symbol::{Interns, ModuleId}; + use roc_solve::solve::SubsByModule; use roc_types::subs::Subs; use std::collections::HashMap; diff --git a/compiler/tests/test_uniqueness_load.rs b/compiler/tests/test_uniqueness_load.rs index ff7ed6bf71..9d0846c8a1 100644 --- a/compiler/tests/test_uniqueness_load.rs +++ b/compiler/tests/test_uniqueness_load.rs @@ -17,12 +17,12 @@ mod test_uniqueness_load { use inlinable_string::InlinableString; use roc::load::{load, LoadedModule}; use roc::pretty_print_types::{content_to_string, name_all_type_vars}; - use roc::solve::SubsByModule; use roc::unique_builtins; use roc_can::def::Declaration::*; use roc_can::def::Def; use roc_collections::all::MutMap; use roc_module::symbol::{Interns, ModuleId}; + use roc_solve::solve::SubsByModule; use roc_types::subs::Subs; use std::collections::HashMap; diff --git a/compiler/unify/Cargo.toml b/compiler/unify/Cargo.toml new file mode 100644 index 0000000000..9eb34a086c --- /dev/null +++ b/compiler/unify/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "roc_unify" +version = "0.1.0" +authors = ["Richard Feldman "] +edition = "2018" + +[dependencies] +roc_collections = { path = "../collections" } +roc_module = { path = "../module" } +roc_types = { path = "../types" } + +[dev-dependencies] +pretty_assertions = "0.5.1 " +maplit = "1.0.1" +indoc = "0.3.3" +quickcheck = "0.8" +quickcheck_macros = "0.8" diff --git a/compiler/unify/src/lib.rs b/compiler/unify/src/lib.rs new file mode 100644 index 0000000000..2bb083f4bc --- /dev/null +++ b/compiler/unify/src/lib.rs @@ -0,0 +1,14 @@ +#![warn(clippy::all, clippy::dbg_macro)] +// I'm skeptical that clippy:large_enum_variant is a good lint to have globally enabled. +// +// It warns about a performance problem where the only quick remediation is +// to allocate more on the heap, which has lots of tradeoffs - including making it +// long-term unclear which allocations *need* to happen for compilation's sake +// (e.g. recursive structures) versus those which were only added to appease clippy. +// +// Effectively optimizing data struture memory layout isn't a quick fix, +// and encouraging shortcuts here creates bad incentives. I would rather temporarily +// re-enable this when working on performance optimizations than have it block PRs. +#![allow(clippy::large_enum_variant)] + +pub mod unify; diff --git a/compiler/src/unify.rs b/compiler/unify/src/unify.rs similarity index 100% rename from compiler/src/unify.rs rename to compiler/unify/src/unify.rs