This commit is contained in:
Richard Feldman 2019-08-25 21:59:19 -04:00
parent 04d3f68192
commit 3fc3059915
7 changed files with 42 additions and 14 deletions

View file

@ -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,

View file

@ -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<String, Type>;
pub fn constrain(
bound_vars: BoundTypeVars,
subs: &mut Subs,
loc_expr: Located<Expr>,
expected: Expected<Type>,
) -> 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();

21
src/infer.rs Normal file
View file

@ -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<Expr>) -> 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
}

View file

@ -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;

View file

@ -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")
}
}

View file

@ -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)
}

View file

@ -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
},