From 3fc305991570cf466965b5dffd42b2dfa6bc55d8 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sun, 25 Aug 2019 21:59:19 -0400 Subject: [PATCH] wip2 --- src/canonicalize.rs | 2 +- src/constrain.rs | 6 +++--- src/infer.rs | 21 +++++++++++++++++++++ src/lib.rs | 1 + src/solve.rs | 16 ++++++++-------- src/subs.rs | 6 ++++++ tests/test_canonicalize.rs | 4 ++-- 7 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 src/infer.rs diff --git a/src/canonicalize.rs b/src/canonicalize.rs index 743d9d3038..50270fd01a 100644 --- a/src/canonicalize.rs +++ b/src/canonicalize.rs @@ -1166,7 +1166,7 @@ fn canonicalize_pattern( // This is a fresh identifier that wasn't already in scope. // Add it to scope! - let symbol_and_region = (symbol.clone(), region); + let symbol_and_region = (symbol.clone(), region.clone()); // Add this to both scope.idents *and* shadowable_idents. // The latter is relevant when recursively canonicalizing Variant patterns, diff --git a/src/constrain.rs b/src/constrain.rs index 2d6d79baa5..29dae22a92 100644 --- a/src/constrain.rs +++ b/src/constrain.rs @@ -13,7 +13,6 @@ use types::Constraint::{self, *}; /// blah mapping = /// nested : Map k v # <-- the same k and v from the top-level annotation /// nested = mapping -/// /// 42 /// /// In elm/compiler this is called RTV - the "Rigid Type Variables" dictionary. @@ -21,6 +20,7 @@ type BoundTypeVars = ImMap; pub fn constrain( bound_vars: BoundTypeVars, + subs: &mut Subs, loc_expr: Located, expected: Expected, ) -> Constraint { @@ -63,7 +63,7 @@ pub fn constrain_def( flex_vars: state.vars, header: state.headers, header_constraint: And(state.reversed_constraints), - body_constraint: constrain(bound_vars, loc_expr, NoExpectation(args.ret_type)) + body_constraint: constrain(bound_vars, subs, loc_expr, NoExpectation(args.ret_type)) })), body_constraint, header: panic!("TODO Map.singleton name (A.At region tipe)"), @@ -84,7 +84,7 @@ pub fn constrain_procedure( }; let args = constrain_args(proc.args.into_iter(), subs, &mut state); let body_type = NoExpectation(args.ret_type); - let body_constraint = constrain(bound_vars, proc.body, body_type); + let body_constraint = constrain(bound_vars, subs, proc.body, body_type); state.reversed_constraints.reverse(); diff --git a/src/infer.rs b/src/infer.rs new file mode 100644 index 0000000000..d17ef0f77e --- /dev/null +++ b/src/infer.rs @@ -0,0 +1,21 @@ +use canonicalize::Expr; +use region::Located; +use subs::{Subs, Content}; +use types::Expected::*; +use types::Type::*; +use collections::ImMap; +use solve::solve; +use constrain::constrain; + +pub fn infer(loc_expr: Located) -> Content { + let mut subs = Subs::new(); + let bound_vars = ImMap::default(); + let variable = subs.mk_flex_var(); + let expected = NoExpectation(Variable(variable)); + let constraint = constrain(bound_vars, &mut subs, loc_expr, expected); + + solve(&mut subs, constraint); + + subs.get(variable).content +} + diff --git a/src/lib.rs b/src/lib.rs index 31effc6599..afb8b9fa64 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ pub mod subs; pub mod constrain; pub mod solve; pub mod unify; +pub mod infer; extern crate im_rc; extern crate fraction; diff --git a/src/solve.rs b/src/solve.rs index 9387edc2cc..247fc6c1d7 100644 --- a/src/solve.rs +++ b/src/solve.rs @@ -16,14 +16,6 @@ use subs::{Subs, Variable}; use types::Constraint::{self, *}; use types::Type::{self, *}; -use unify::unify; - -pub fn type_to_variable(subs: &mut Subs, typ: Type) -> Variable { - match typ { - Variable(var) => var, - - } -} pub fn solve(subs: &mut Subs, constraint: Constraint) { match constraint { @@ -96,3 +88,11 @@ pub fn solve(subs: &mut Subs, constraint: Constraint) { }, } } + +fn type_to_variable(subs: &mut Subs, typ: Type) -> Variable { + match typ { + Variable(var) => var, + _ => panic!("TODO type_to_var") + } +} + diff --git a/src/subs.rs b/src/subs.rs index bbcfdcfa92..d58539d3fa 100644 --- a/src/subs.rs +++ b/src/subs.rs @@ -26,6 +26,12 @@ impl UnifyKey for Variable { } impl Subs { + pub fn new() -> Self { + Subs { + utable: UnificationTable::default() + } + } + pub fn fresh(&mut self, value: Descriptor) -> Variable { self.utable.new_key(value) } diff --git a/tests/test_canonicalize.rs b/tests/test_canonicalize.rs index eeae6d3340..1ebceb5c8a 100644 --- a/tests/test_canonicalize.rs +++ b/tests/test_canonicalize.rs @@ -116,7 +116,7 @@ mod test_canonicalize { name: Some("func".to_string()), is_self_tail_recursive: false, definition: empty_region(), - args: vec![Pattern::Identifier(sym("arg"))], + args: vec![loc(Pattern::Identifier(sym("arg")))], body: loc(Expr::Operator( loc_box(Expr::Var(sym("arg"))), loc(Operator::Plus), @@ -401,7 +401,7 @@ mod test_canonicalize { match expr { Assign(assignments, _) => { assignments.into_iter().map(|(pattern, _)| { - match pattern { + match pattern.value { Identifier(symbol) => { symbol },