mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-13 09:49:11 +03:00
Merge branch 'trunk' into edit_big_string
This commit is contained in:
commit
a1a08fbb8a
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3060,6 +3060,7 @@ dependencies = [
|
||||
"roc_reporting",
|
||||
"roc_solve",
|
||||
"roc_types",
|
||||
"roc_unify",
|
||||
"ropey",
|
||||
"serde",
|
||||
"snafu",
|
||||
|
@ -89,4 +89,16 @@ impl<T> Expected<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_ref<U>(&self, new: U) -> Expected<U> {
|
||||
match self {
|
||||
Expected::NoExpectation(_val) => Expected::NoExpectation(new),
|
||||
Expected::ForReason(reason, _val, region) => {
|
||||
Expected::ForReason(reason.clone(), new, *region)
|
||||
}
|
||||
Expected::FromAnnotation(pattern, size, source, _val) => {
|
||||
Expected::FromAnnotation(pattern.clone(), *size, *source, new)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,6 +409,18 @@ pub fn canonicalize_expr<'a>(
|
||||
ast::Expr::Var { module_name, ident } => {
|
||||
canonicalize_lookup(env, scope, module_name, ident, region)
|
||||
}
|
||||
ast::Expr::Underscore(name) => {
|
||||
// we parse underscores, but they are not valid expression syntax
|
||||
let problem = roc_problem::can::RuntimeError::MalformedIdentifier(
|
||||
(*name).into(),
|
||||
roc_parse::ident::BadIdent::Underscore(region.start_line, region.start_col),
|
||||
region,
|
||||
);
|
||||
|
||||
env.problem(Problem::RuntimeError(problem.clone()));
|
||||
|
||||
(RuntimeError(problem), Output::default())
|
||||
}
|
||||
ast::Expr::Defs(loc_defs, loc_ret) => {
|
||||
can_defs_with_return(
|
||||
env,
|
||||
|
@ -119,6 +119,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
|
||||
| Str(_)
|
||||
| AccessorFunction(_)
|
||||
| Var { .. }
|
||||
| Underscore { .. }
|
||||
| MalformedIdent(_, _)
|
||||
| MalformedClosure
|
||||
| PrecedenceConflict { .. }
|
||||
|
@ -198,7 +198,7 @@ pub fn canonicalize_pattern<'a>(
|
||||
|
||||
Underscore(_) => match pattern_type {
|
||||
WhenBranch | FunctionArg => Pattern::Underscore,
|
||||
ptype => unsupported_pattern(env, ptype, region),
|
||||
TopLevelDef | DefExpr => bad_underscore(env, region),
|
||||
},
|
||||
|
||||
NumLiteral(string) => match pattern_type {
|
||||
@ -402,7 +402,21 @@ pub fn canonicalize_pattern<'a>(
|
||||
/// When we detect an unsupported pattern type (e.g. 5 = 1 + 2 is unsupported because you can't
|
||||
/// assign to Int patterns), report it to Env and return an UnsupportedPattern runtime error pattern.
|
||||
fn unsupported_pattern(env: &mut Env, pattern_type: PatternType, region: Region) -> Pattern {
|
||||
env.problem(Problem::UnsupportedPattern(pattern_type, region));
|
||||
use roc_problem::can::BadPattern;
|
||||
env.problem(Problem::UnsupportedPattern(
|
||||
BadPattern::Unsupported(pattern_type),
|
||||
region,
|
||||
));
|
||||
|
||||
Pattern::UnsupportedPattern(region)
|
||||
}
|
||||
|
||||
fn bad_underscore(env: &mut Env, region: Region) -> Pattern {
|
||||
use roc_problem::can::BadPattern;
|
||||
env.problem(Problem::UnsupportedPattern(
|
||||
BadPattern::UnderscoreInDef,
|
||||
region,
|
||||
));
|
||||
|
||||
Pattern::UnsupportedPattern(region)
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||
| Access(_, _)
|
||||
| AccessorFunction(_)
|
||||
| Var { .. }
|
||||
| Underscore { .. }
|
||||
| MalformedIdent(_, _)
|
||||
| MalformedClosure
|
||||
| GlobalTag(_)
|
||||
@ -189,6 +190,10 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
||||
|
||||
buf.push_str(ident);
|
||||
}
|
||||
Underscore(name) => {
|
||||
buf.push('_');
|
||||
buf.push_str(name);
|
||||
}
|
||||
Apply(loc_expr, loc_args, _) => {
|
||||
if apply_needs_parens {
|
||||
buf.push('(');
|
||||
|
@ -115,6 +115,8 @@ pub enum Expr<'a> {
|
||||
ident: &'a str,
|
||||
},
|
||||
|
||||
Underscore(&'a str),
|
||||
|
||||
// Tags
|
||||
GlobalTag(&'a str),
|
||||
PrivateTag(&'a str),
|
||||
|
@ -192,6 +192,30 @@ fn record_field_access<'a>() -> impl Parser<'a, &'a str, EExpr<'a>> {
|
||||
)
|
||||
}
|
||||
|
||||
/// In some contexts we want to parse the `_` as an expression, so it can then be turned into a
|
||||
/// pattern later
|
||||
fn parse_loc_term_or_underscore<'a>(
|
||||
min_indent: u16,
|
||||
options: ExprParseOptions,
|
||||
arena: &'a Bump,
|
||||
state: State<'a>,
|
||||
) -> ParseResult<'a, Located<Expr<'a>>, EExpr<'a>> {
|
||||
one_of!(
|
||||
loc_expr_in_parens_etc_help(min_indent),
|
||||
loc!(specialize(EExpr::Str, string_literal_help())),
|
||||
loc!(specialize(EExpr::Number, positive_number_literal_help())),
|
||||
loc!(specialize(EExpr::Lambda, closure_help(min_indent, options))),
|
||||
loc!(underscore_expression()),
|
||||
loc!(record_literal_help(min_indent)),
|
||||
loc!(specialize(EExpr::List, list_literal_help(min_indent))),
|
||||
loc!(map_with_arena!(
|
||||
assign_or_destructure_identifier(),
|
||||
ident_to_expr
|
||||
)),
|
||||
)
|
||||
.parse(arena, state)
|
||||
}
|
||||
|
||||
fn parse_loc_term<'a>(
|
||||
min_indent: u16,
|
||||
options: ExprParseOptions,
|
||||
@ -213,6 +237,26 @@ fn parse_loc_term<'a>(
|
||||
.parse(arena, state)
|
||||
}
|
||||
|
||||
fn underscore_expression<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> {
|
||||
move |arena: &'a Bump, state: State<'a>| {
|
||||
let (_, _, next_state) = word1(b'_', EExpr::Underscore).parse(arena, state)?;
|
||||
|
||||
let lowercase_ident_expr = {
|
||||
let row = state.line;
|
||||
let col = state.column;
|
||||
|
||||
specialize(move |_, _, _| EExpr::End(row, col), lowercase_ident())
|
||||
};
|
||||
|
||||
let (_, output, final_state) = optional(lowercase_ident_expr).parse(arena, next_state)?;
|
||||
|
||||
match output {
|
||||
Some(name) => Ok((MadeProgress, Expr::Underscore(name), final_state)),
|
||||
None => Ok((MadeProgress, Expr::Underscore(&""), final_state)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn loc_possibly_negative_or_negated_term<'a>(
|
||||
min_indent: u16,
|
||||
options: ExprParseOptions,
|
||||
@ -243,10 +287,7 @@ fn loc_possibly_negative_or_negated_term<'a>(
|
||||
)
|
||||
}
|
||||
)),
|
||||
|arena, state| {
|
||||
// TODO use parse_loc_term_better
|
||||
parse_loc_term(min_indent, options, arena, state)
|
||||
}
|
||||
|arena, state| { parse_loc_term_or_underscore(min_indent, options, arena, state) }
|
||||
]
|
||||
}
|
||||
|
||||
@ -1316,6 +1357,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
||||
Ok(Pattern::QualifiedIdentifier { module_name, ident })
|
||||
}
|
||||
}
|
||||
Expr::Underscore(opt_name) => Ok(Pattern::Underscore(opt_name)),
|
||||
Expr::GlobalTag(value) => Ok(Pattern::GlobalTag(value)),
|
||||
Expr::PrivateTag(value) => Ok(Pattern::PrivateTag(value)),
|
||||
Expr::Apply(loc_val, loc_args, _) => {
|
||||
|
@ -411,6 +411,7 @@ pub enum EExpr<'a> {
|
||||
If(If<'a>, Row, Col),
|
||||
|
||||
Lambda(ELambda<'a>, Row, Col),
|
||||
Underscore(Row, Col),
|
||||
|
||||
InParens(EInParens<'a>, Row, Col),
|
||||
Record(ERecord<'a>, Row, Col),
|
||||
|
@ -1573,7 +1573,7 @@ mod test_parse {
|
||||
#[test]
|
||||
fn single_underscore_closure() {
|
||||
let arena = Bump::new();
|
||||
let pattern = Located::new(0, 0, 1, 2, Underscore(&""));
|
||||
let pattern = Located::new(0, 0, 1, 2, Pattern::Underscore(&""));
|
||||
let patterns = &[pattern];
|
||||
let expected = Closure(patterns, arena.alloc(Located::new(0, 0, 6, 8, Num("42"))));
|
||||
let actual = parse_expr_with(&arena, "\\_ -> 42");
|
||||
@ -1635,8 +1635,8 @@ mod test_parse {
|
||||
#[test]
|
||||
fn closure_with_underscores() {
|
||||
let arena = Bump::new();
|
||||
let underscore1 = Located::new(0, 0, 1, 2, Underscore(&""));
|
||||
let underscore2 = Located::new(0, 0, 4, 9, Underscore(&"name"));
|
||||
let underscore1 = Located::new(0, 0, 1, 2, Pattern::Underscore(&""));
|
||||
let underscore2 = Located::new(0, 0, 4, 9, Pattern::Underscore(&"name"));
|
||||
let patterns = bumpalo::vec![in &arena; underscore1, underscore2];
|
||||
let expected = Closure(
|
||||
arena.alloc(patterns),
|
||||
@ -1866,6 +1866,49 @@ mod test_parse {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn underscore_backpassing() {
|
||||
let arena = Bump::new();
|
||||
let newlines = bumpalo::vec![in &arena; Newline, Newline];
|
||||
let underscore = Located::new(1, 1, 0, 1, Pattern::Underscore(&""));
|
||||
let identifier_y = Located::new(1, 1, 7, 8, Identifier("y"));
|
||||
|
||||
let num_4 = Num("4");
|
||||
|
||||
let var_y = Var {
|
||||
module_name: "",
|
||||
ident: "y",
|
||||
};
|
||||
let loc_var_y = arena.alloc(Located::new(1, 1, 12, 13, var_y));
|
||||
|
||||
let closure = ParensAround(arena.alloc(Closure(arena.alloc([identifier_y]), loc_var_y)));
|
||||
let loc_closure = Located::new(1, 1, 5, 14, closure);
|
||||
|
||||
let ret = Expr::SpaceBefore(arena.alloc(num_4), newlines.into_bump_slice());
|
||||
let loc_ret = Located::new(3, 3, 0, 1, ret);
|
||||
|
||||
let reset_indentation = bumpalo::vec![in &arena; LineComment(" leading comment")];
|
||||
let expected = Expr::SpaceBefore(
|
||||
arena.alloc(Expr::Backpassing(
|
||||
arena.alloc([underscore]),
|
||||
arena.alloc(loc_closure),
|
||||
arena.alloc(loc_ret),
|
||||
)),
|
||||
reset_indentation.into_bump_slice(),
|
||||
);
|
||||
|
||||
assert_parses_to(
|
||||
indoc!(
|
||||
r#"# leading comment
|
||||
_ <- (\y -> y)
|
||||
|
||||
4
|
||||
"#
|
||||
),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_backpassing() {
|
||||
let arena = Bump::new();
|
||||
@ -2624,7 +2667,7 @@ mod test_parse {
|
||||
guard: None,
|
||||
});
|
||||
let newlines = &[Newline];
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore("")), newlines);
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Pattern::Underscore("")), newlines);
|
||||
let loc_pattern2 = Located::new(3, 3, 4, 5, pattern2);
|
||||
let expr2 = Num("4");
|
||||
let loc_expr2 = Located::new(3, 3, 9, 10, expr2);
|
||||
@ -2661,7 +2704,7 @@ mod test_parse {
|
||||
|
||||
let branch1 = {
|
||||
let newlines = &[Newline];
|
||||
let pattern1 = Pattern::SpaceBefore(arena.alloc(Underscore("")), newlines);
|
||||
let pattern1 = Pattern::SpaceBefore(arena.alloc(Pattern::Underscore("")), newlines);
|
||||
let loc_pattern1 = Located::new(1, 1, 4, 5, pattern1);
|
||||
let num_1 = Num("1");
|
||||
let expr1 = Located::new(
|
||||
@ -2680,7 +2723,8 @@ mod test_parse {
|
||||
};
|
||||
|
||||
let branch2 = {
|
||||
let pattern1 = Pattern::SpaceBefore(arena.alloc(Underscore("")), &[Newline, Newline]);
|
||||
let pattern1 =
|
||||
Pattern::SpaceBefore(arena.alloc(Pattern::Underscore("")), &[Newline, Newline]);
|
||||
let loc_pattern1 = Located::new(4, 4, 4, 5, pattern1);
|
||||
let num_1 = Num("2");
|
||||
let expr1 = Located::new(
|
||||
@ -3576,7 +3620,7 @@ mod test_parse {
|
||||
guard: None,
|
||||
});
|
||||
let newlines = &[Newline];
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore(&"")), newlines);
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Pattern::Underscore(&"")), newlines);
|
||||
let loc_pattern2 = Located::new(2, 2, 4, 5, pattern2);
|
||||
let expr2 = Num("4");
|
||||
let loc_expr2 = Located::new(2, 2, 9, 10, expr2);
|
||||
@ -3621,7 +3665,7 @@ mod test_parse {
|
||||
guard: None,
|
||||
});
|
||||
let newlines = &[Newline];
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore(&"")), newlines);
|
||||
let pattern2 = Pattern::SpaceBefore(arena.alloc(Pattern::Underscore(&"")), newlines);
|
||||
let loc_pattern2 = Located::new(2, 2, 4, 5, pattern2);
|
||||
let expr2 = Num("4");
|
||||
let loc_expr2 = Located::new(2, 2, 9, 10, expr2);
|
||||
|
@ -14,6 +14,12 @@ pub struct CycleEntry {
|
||||
pub expr_region: Region,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum BadPattern {
|
||||
UnderscoreInDef,
|
||||
Unsupported(PatternType),
|
||||
}
|
||||
|
||||
/// Problems that can occur in the course of canonicalization.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Problem {
|
||||
@ -25,7 +31,7 @@ pub enum Problem {
|
||||
UnusedArgument(Symbol, Symbol, Region),
|
||||
PrecedenceProblem(PrecedenceProblem),
|
||||
// Example: (5 = 1 + 2) is an unsupported pattern in an assignment; Int patterns aren't allowed in assignments!
|
||||
UnsupportedPattern(PatternType, Region),
|
||||
UnsupportedPattern(BadPattern, Region),
|
||||
ShadowingInAnnotation {
|
||||
original_region: Region,
|
||||
shadow: Located<Ident>,
|
||||
|
@ -2,7 +2,7 @@ use roc_collections::all::MutSet;
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_parse::parser::{Col, Row};
|
||||
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
||||
use roc_problem::can::{FloatErrorKind, IntErrorKind, Problem, RuntimeError};
|
||||
use roc_problem::can::{BadPattern, FloatErrorKind, IntErrorKind, Problem, RuntimeError};
|
||||
use roc_region::all::Region;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -103,7 +103,11 @@ pub fn can_problem<'b>(
|
||||
},
|
||||
alloc.region(region),
|
||||
]),
|
||||
Problem::UnsupportedPattern(pattern_type, region) => {
|
||||
Problem::UnsupportedPattern(BadPattern::UnderscoreInDef, region) => alloc.stack(vec![
|
||||
alloc.reflow("Underscore patterns are not allowed in definitions"),
|
||||
alloc.region(region),
|
||||
]),
|
||||
Problem::UnsupportedPattern(BadPattern::Unsupported(pattern_type), region) => {
|
||||
use roc_parse::pattern::PatternType::*;
|
||||
|
||||
let this_thing = match pattern_type {
|
||||
|
@ -6334,4 +6334,27 @@ mod test_reporting {
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn underscore_let() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
_ = 3
|
||||
|
||||
4
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
Underscore patterns are not allowed in definitions
|
||||
|
||||
1│ _ = 3
|
||||
^
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ pub enum PReason {
|
||||
OptionalField,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AnnotationSource {
|
||||
TypedIfBranch { index: Index, num_branches: usize },
|
||||
TypedWhenBranch { index: Index },
|
||||
|
@ -15,6 +15,7 @@ roc_region = { path = "../compiler/region" }
|
||||
roc_module = { path = "../compiler/module" }
|
||||
roc_problem = { path = "../compiler/problem" }
|
||||
roc_types = { path = "../compiler/types" }
|
||||
roc_unify = { path = "../compiler/unify" }
|
||||
roc_fmt = { path = "../compiler/fmt" }
|
||||
roc_reporting = { path = "../compiler/reporting" }
|
||||
roc_solve = { path = "../compiler/solve" }
|
||||
|
@ -7,4 +7,5 @@ mod pattern;
|
||||
pub mod pool;
|
||||
pub mod roc_file;
|
||||
pub mod scope;
|
||||
pub mod solve;
|
||||
pub mod types;
|
||||
|
@ -153,7 +153,7 @@ pub fn to_pattern2<'a>(
|
||||
|
||||
Underscore(_) => match pattern_type {
|
||||
WhenBranch | FunctionArg => Pattern2::Underscore,
|
||||
ptype => unsupported_pattern(env, ptype, region),
|
||||
TopLevelDef | DefExpr => underscore_in_def(env, region),
|
||||
},
|
||||
|
||||
FloatLiteral(ref string) => match pattern_type {
|
||||
@ -521,7 +521,21 @@ fn unsupported_pattern<'a>(
|
||||
pattern_type: PatternType,
|
||||
region: Region,
|
||||
) -> Pattern2 {
|
||||
env.problem(Problem::UnsupportedPattern(pattern_type, region));
|
||||
use roc_problem::can::BadPattern;
|
||||
env.problem(Problem::UnsupportedPattern(
|
||||
BadPattern::Unsupported(pattern_type),
|
||||
region,
|
||||
));
|
||||
|
||||
Pattern2::UnsupportedPattern(region)
|
||||
}
|
||||
|
||||
fn underscore_in_def<'a>(env: &mut Env<'a>, region: Region) -> Pattern2 {
|
||||
use roc_problem::can::BadPattern;
|
||||
env.problem(Problem::UnsupportedPattern(
|
||||
BadPattern::UnderscoreInDef,
|
||||
region,
|
||||
));
|
||||
|
||||
Pattern2::UnsupportedPattern(region)
|
||||
}
|
||||
|
1595
editor/src/lang/solve.rs
Normal file
1595
editor/src/lang/solve.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,45 +5,50 @@ extern crate indoc;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use roc_can::expected::Expected;
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_editor::lang::solve;
|
||||
use roc_editor::lang::{
|
||||
constrain::constrain_expr,
|
||||
constrain::Constraint,
|
||||
expr::{str_to_expr2, Env},
|
||||
pool::Pool,
|
||||
scope::Scope,
|
||||
types::Type2,
|
||||
};
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_module::symbol::{IdentIds, ModuleIds};
|
||||
use roc_region::all::Region;
|
||||
use roc_solve::module::run_solve;
|
||||
use roc_types::{pretty_print::content_to_string, subs::VarStore, types::Type};
|
||||
use roc_types::solved_types::Solved;
|
||||
use roc_types::subs::{Subs, Variable};
|
||||
use roc_types::{pretty_print::content_to_string, subs::VarStore};
|
||||
|
||||
fn ed_constraint_to_can_constraint(
|
||||
constraint: roc_editor::lang::constrain::Constraint,
|
||||
) -> roc_can::constraint::Constraint {
|
||||
match constraint {
|
||||
roc_editor::lang::constrain::Constraint::Eq(typ, expected, category, region) => {
|
||||
let new_typ = type2_to_type(&typ);
|
||||
let expected_typ = expected.get_type_ref();
|
||||
fn run_solve(
|
||||
mempool: &mut Pool,
|
||||
aliases: MutMap<Symbol, roc_types::types::Alias>,
|
||||
rigid_variables: MutMap<Variable, Lowercase>,
|
||||
constraint: Constraint,
|
||||
var_store: VarStore,
|
||||
) -> (Solved<Subs>, solve::Env, Vec<solve::TypeError>) {
|
||||
let env = solve::Env {
|
||||
vars_by_symbol: MutMap::default(),
|
||||
aliases,
|
||||
};
|
||||
|
||||
let expected_typ = type2_to_type(expected_typ);
|
||||
let mut subs = Subs::new(var_store.into());
|
||||
|
||||
roc_can::constraint::Constraint::Eq(
|
||||
new_typ,
|
||||
expected.replace(expected_typ),
|
||||
category,
|
||||
region,
|
||||
)
|
||||
}
|
||||
_ => todo!("{:?}", constraint),
|
||||
for (var, name) in rigid_variables {
|
||||
subs.rigid_var(var, name);
|
||||
}
|
||||
}
|
||||
|
||||
fn type2_to_type(typ: &Type2) -> Type {
|
||||
match typ {
|
||||
Type2::Apply(symbol, _) => Type::Apply(*symbol, Vec::new()),
|
||||
Type2::Variable(var) => Type::Variable(*var),
|
||||
_ => todo!("{:?}", typ),
|
||||
}
|
||||
// Now that the module is parsed, canonicalized, and constrained,
|
||||
// we need to type check it.
|
||||
let mut problems = Vec::new();
|
||||
|
||||
// Run the solver to populate Subs.
|
||||
let (solved_subs, solved_env) = solve::run(mempool, &env, &mut problems, subs, &constraint);
|
||||
|
||||
(solved_subs, solved_env, problems)
|
||||
}
|
||||
|
||||
fn infer_eq(actual: &str, expected_str: &str) {
|
||||
@ -83,20 +88,29 @@ fn infer_eq(actual: &str, expected_str: &str) {
|
||||
Expected::NoExpectation(Type2::Variable(var)),
|
||||
);
|
||||
|
||||
let constraint = ed_constraint_to_can_constraint(constraint);
|
||||
let Env {
|
||||
pool,
|
||||
var_store: ref_var_store,
|
||||
..
|
||||
} = env;
|
||||
|
||||
// extract the var_store out of the env again
|
||||
let mut var_store = VarStore::default();
|
||||
std::mem::swap(ref_var_store, &mut var_store);
|
||||
|
||||
let (mut solved, _, _) = run_solve(
|
||||
pool,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
constraint,
|
||||
var_store,
|
||||
);
|
||||
|
||||
let mut subs = solved.inner_mut();
|
||||
let subs = solved.inner_mut();
|
||||
|
||||
let content = subs.get(var).content;
|
||||
|
||||
let actual_str = content_to_string(content, &mut subs, mod_id, &Default::default());
|
||||
let actual_str = content_to_string(content, &subs, mod_id, &Default::default());
|
||||
|
||||
assert_eq!(actual_str, expected_str);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ app "http-get"
|
||||
|
||||
main : Task.Task {} *
|
||||
main =
|
||||
{} <- await (Stdout.line "What URL should I get?")
|
||||
_ <- await (Stdout.line "What URL should I get?")
|
||||
|
||||
url <- await Stdin.line
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user