Get tests compiling again

This commit is contained in:
Richard Feldman 2019-10-16 23:38:12 -04:00
parent ae301f3c86
commit f74f0f6ab7
6 changed files with 36 additions and 69 deletions

View file

@ -111,7 +111,7 @@ fn canonicalize_expr<'a>(
), ),
ast::Expr::Record(fields) => { ast::Expr::Record(fields) => {
if fields.is_empty() { if fields.is_empty() {
constraints.add(Eq(EmptyRec, expected, region)); constraints.add(Eq(EmptyRec, expected, region.clone()));
(EmptyRecord, Output::new()) (EmptyRecord, Output::new())
} else { } else {
@ -119,7 +119,7 @@ fn canonicalize_expr<'a>(
} }
} }
ast::Expr::Str(string) => { ast::Expr::Str(string) => {
constraints.add(Eq(constrain::str_type(), expected, region)); constraints.add(Eq(constrain::str_type(), expected, region.clone()));
(Str((*string).into()), Output::new()) (Str((*string).into()), Output::new())
} }
@ -130,7 +130,7 @@ fn canonicalize_expr<'a>(
constraints.add(Eq( constraints.add(Eq(
constrain::empty_list_type(subs.mk_flex_var()), constrain::empty_list_type(subs.mk_flex_var()),
expected, expected,
region, region.clone(),
)); ));
(EmptyList, output) (EmptyList, output)
@ -165,7 +165,11 @@ fn canonicalize_expr<'a>(
can_elems.push(can_expr); can_elems.push(can_expr);
} }
constraints.add(Eq(constrain::list_type(list_type), expected, region)); constraints.add(Eq(
constrain::list_type(list_type),
expected,
region.clone(),
));
// A list literal is never a tail call! // A list literal is never a tail call!
output.tail_call = None; output.tail_call = None;

View file

@ -377,41 +377,6 @@ pub fn str_type() -> Type {
builtin_type("Str", "Str", Vec::new()) builtin_type("Str", "Str", Vec::new())
} }
fn list(
loc_elems: Vec<Located<Expr>>,
bound_vars: &BoundTypeVars,
subs: &mut Subs,
expected: Expected<Type>,
region: Region,
) -> Constraint {
let list_var = subs.mk_flex_var(); // `v` in the type (List v)
let list_type = Type::Variable(list_var);
let mut constraints = Vec::with_capacity(1 + (loc_elems.len() * 2));
for loc_elem in loc_elems {
let elem_var = subs.mk_flex_var();
let elem_type = Variable(elem_var);
let elem_expected = NoExpectation(elem_type.clone());
let elem_constraint = constrain(bound_vars, subs, loc_elem, elem_expected);
let list_elem_constraint = Eq(
list_type.clone(),
ForReason(Reason::ElemInList, elem_type, region.clone()),
region.clone(),
);
constraints.push(elem_constraint);
constraints.push(list_elem_constraint);
}
constraints.push(Eq(
builtin_type("List", "List", vec![list_type]),
expected,
region,
));
And(constraints)
}
// pub fn constrain_def( // pub fn constrain_def(
// loc_pattern: Located<Pattern>, // loc_pattern: Located<Pattern>,
// loc_expr: Located<Expr>, // loc_expr: Located<Expr>,

View file

@ -592,21 +592,6 @@ fn gen() {
.expect("Cannot re-add previously compiled function."); .expect("Cannot re-add previously compiled function.");
} }
// TODO write a function which takes a context and expr (etc) and panics
// if the given expr is not a function expr, and then takes the contents
// of that function and writes them all to the context.
//
// For now, it needs to support only Float values.
//
// The function doesn't need to take any arguments yet. In fact, it can
// just return 12345.
//
// The whole key here is that we want a main function which looks like:
//
// fn main() -> f64 { return 12345; }
//
// we want fn_val to be equal to that, so we can name it "main" and run it.
// make main(), a function which returns an f64 // make main(), a function which returns an f64
Emitter::compile(&context, &builder, &fpm, &module, &function).expect("Error compiling main"); Emitter::compile(&context, &builder, &fpm, &module, &function).expect("Error compiling main");
@ -628,6 +613,6 @@ fn gen() {
}; };
unsafe { unsafe {
panic!("=> {}", compiled_fn.call()); assert_eq!(12345.0, compiled_fn.call());
} }
} }

View file

@ -27,6 +27,7 @@ pub fn solve<'a>(env: &Env<'a>, subs: &mut Subs, constraint: &Constraint) {
subs.union(actual, expected); subs.union(actual, expected);
} }
And(sub_constraints) => { And(sub_constraints) => {
// TODO drop And - we shouldn't need it anymore
for sub_constraint in sub_constraints.iter() { for sub_constraint in sub_constraints.iter() {
solve(env, subs, sub_constraint); solve(env, subs, sub_constraint);
} }

View file

@ -9,21 +9,28 @@ use roc::can::procedure::Procedure;
use roc::can::symbol::Symbol; use roc::can::symbol::Symbol;
use roc::can::Output; use roc::can::Output;
use roc::collections::{ImMap, MutMap}; use roc::collections::{ImMap, MutMap};
use roc::constrain::Constraints;
use roc::ident::Ident; use roc::ident::Ident;
use roc::parse; use roc::parse;
use roc::parse::ast::{self, Attempting}; use roc::parse::ast::{self, Attempting};
use roc::parse::blankspace::space0_before; use roc::parse::blankspace::space0_before;
use roc::parse::parser::{loc, map, Fail, Parser, State}; use roc::parse::parser::{loc, Fail, Parser, State};
use roc::region::{Located, Region}; use roc::region::{Located, Region};
use roc::subs::Subs;
use roc::types::{Expected, Type};
pub fn parse_with<'a>(arena: &'a Bump, input: &'a str) -> Result<ast::Expr<'a>, Fail> { pub fn parse_with<'a>(arena: &'a Bump, input: &'a str) -> Result<ast::Expr<'a>, Fail> {
parse_loc_with(arena, input).map(|loc_expr| loc_expr.value)
}
pub fn parse_loc_with<'a>(arena: &'a Bump, input: &'a str) -> Result<Located<ast::Expr<'a>>, Fail> {
let state = State::new(&input, Attempting::Module); let state = State::new(&input, Attempting::Module);
let parser = map(space0_before(loc(parse::expr(0)), 0), |loc_expr| { let parser = space0_before(loc(parse::expr(0)), 0);
loc_expr.value
});
let answer = parser.parse(&arena, state); let answer = parser.parse(&arena, state);
answer.map(|(expr, _)| expr).map_err(|(fail, _)| fail) answer
.map(|(loc_expr, _)| loc_expr)
.map_err(|(fail, _)| fail)
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -45,23 +52,29 @@ pub fn can_expr_with(
declared_idents: &ImMap<Ident, (Symbol, Region)>, declared_idents: &ImMap<Ident, (Symbol, Region)>,
declared_variants: &ImMap<Symbol, Located<Box<str>>>, declared_variants: &ImMap<Symbol, Located<Box<str>>>,
) -> (Expr, Output, Vec<Problem>, MutMap<Symbol, Procedure>) { ) -> (Expr, Output, Vec<Problem>, MutMap<Symbol, Procedure>) {
let expr = parse_with(&arena, expr_str).unwrap_or_else(|_| { let loc_expr = parse_loc_with(&arena, expr_str).unwrap_or_else(|_| {
panic!( panic!(
"can_expr_with() got a parse error when attempting to canonicalize:\n\n{:?}", "can_expr_with() got a parse error when attempting to canonicalize:\n\n{:?}",
expr_str expr_str
) )
}); });
let home = "Test".to_string(); let mut subs = Subs::new();
let arena = Bump::new(); let mut constraints = Constraints::new();
let variable = subs.mk_flex_var();
let expected = Expected::NoExpectation(Type::Variable(variable));
let home = "Test";
let (loc_expr, output, problems, procedures) = can::canonicalize_declaration( let (loc_expr, output, problems, procedures) = can::canonicalize_declaration(
arena, arena,
home, &mut constraints,
name, &mut subs,
home.into(),
name.into(),
Region::zero(), Region::zero(),
&expr, loc_expr,
declared_idents, declared_idents,
declared_variants, declared_variants,
expected,
); );
(loc_expr.value, output, problems, procedures) (loc_expr.value, output, problems, procedures)

View file

@ -3,13 +3,13 @@ extern crate pretty_assertions;
#[macro_use] #[macro_use]
extern crate indoc; extern crate indoc;
extern crate bumpalo;
extern crate roc; extern crate roc;
mod helpers; mod helpers;
#[cfg(test)] #[cfg(test)]
mod test_infer { mod test_infer {
use bumpalo::Bump;
use helpers::can_expr; use helpers::can_expr;
use roc::infer::infer_expr; use roc::infer::infer_expr;
use roc::pretty_print_types::content_to_string; use roc::pretty_print_types::content_to_string;
@ -19,9 +19,8 @@ mod test_infer {
// HELPERS // HELPERS
fn infer_eq(src: &str, expected: &str) { fn infer_eq(src: &str, expected: &str) {
let arena = Bump::new();
let (expr, _, _, procedures) = can_expr(src); let (expr, _, _, procedures) = can_expr(src);
let mut subs = Subs::new(&arena); let mut subs = Subs::new();
let content = infer_expr(&mut subs, Located::new(0, 0, 0, 0, expr), procedures); let content = infer_expr(&mut subs, Located::new(0, 0, 0, 0, expr), procedures);
let actual_str = content_to_string(content, &mut subs); let actual_str = content_to_string(content, &mut subs);