mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
Constrain optional fields
This commit is contained in:
parent
1bdfe578bd
commit
7330e82f75
@ -1,4 +1,5 @@
|
||||
use crate::env::Env;
|
||||
use crate::expr::Expr;
|
||||
use crate::num::{finish_parsing_base, finish_parsing_float, finish_parsing_int};
|
||||
use crate::scope::Scope;
|
||||
use roc_module::ident::{Ident, Lowercase, TagName};
|
||||
@ -50,7 +51,7 @@ pub struct RecordDestruct {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum DestructType {
|
||||
Required,
|
||||
Optional(Variable),
|
||||
Optional(Variable, Located<Expr>),
|
||||
Guard(Variable, Located<Pattern>),
|
||||
}
|
||||
|
||||
|
@ -327,6 +327,7 @@ pub fn constrain_expr(
|
||||
pattern_types.push(pattern_type);
|
||||
|
||||
constrain_pattern(
|
||||
env,
|
||||
&loc_pattern.value,
|
||||
loc_pattern.region,
|
||||
pattern_expected,
|
||||
@ -843,6 +844,7 @@ fn constrain_when_branch(
|
||||
// then unify that variable with the expectation?
|
||||
for loc_pattern in &when_branch.patterns {
|
||||
constrain_pattern(
|
||||
env,
|
||||
&loc_pattern.value,
|
||||
loc_pattern.region,
|
||||
pattern_expected.clone(),
|
||||
@ -947,7 +949,11 @@ pub fn constrain_decls(
|
||||
constraint
|
||||
}
|
||||
|
||||
fn constrain_def_pattern(loc_pattern: &Located<Pattern>, expr_type: Type) -> PatternState {
|
||||
fn constrain_def_pattern(
|
||||
env: &Env,
|
||||
loc_pattern: &Located<Pattern>,
|
||||
expr_type: Type,
|
||||
) -> PatternState {
|
||||
let pattern_expected = PExpected::NoExpectation(expr_type);
|
||||
|
||||
let mut state = PatternState {
|
||||
@ -957,6 +963,7 @@ fn constrain_def_pattern(loc_pattern: &Located<Pattern>, expr_type: Type) -> Pat
|
||||
};
|
||||
|
||||
constrain_pattern(
|
||||
env,
|
||||
&loc_pattern.value,
|
||||
loc_pattern.region,
|
||||
pattern_expected,
|
||||
@ -970,7 +977,7 @@ fn constrain_def(env: &Env, def: &Def, body_con: Constraint) -> Constraint {
|
||||
let expr_var = def.expr_var;
|
||||
let expr_type = Type::Variable(expr_var);
|
||||
|
||||
let mut pattern_state = constrain_def_pattern(&def.loc_pattern, expr_type.clone());
|
||||
let mut pattern_state = constrain_def_pattern(env, &def.loc_pattern, expr_type.clone());
|
||||
|
||||
pattern_state.vars.push(expr_var);
|
||||
|
||||
@ -1117,6 +1124,7 @@ pub fn rec_defs_help(
|
||||
};
|
||||
|
||||
constrain_pattern(
|
||||
env,
|
||||
&def.loc_pattern.value,
|
||||
def.loc_pattern.region,
|
||||
pattern_expected,
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::builtins;
|
||||
use crate::expr::{constrain_expr, Env};
|
||||
use roc_can::constraint::Constraint;
|
||||
use roc_can::expected::{Expected, PExpected};
|
||||
use roc_can::pattern::Pattern::{self, *};
|
||||
@ -8,7 +9,7 @@ use roc_module::ident::Lowercase;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_types::subs::Variable;
|
||||
use roc_types::types::{Category, PReason, PatternCategory, RecordField, Type};
|
||||
use roc_types::types::{Category, PReason, PatternCategory, Reason, RecordField, Type};
|
||||
|
||||
pub struct PatternState {
|
||||
pub headers: SendMap<Symbol, Located<Type>>,
|
||||
@ -120,6 +121,7 @@ fn headers_from_annotation_help(
|
||||
/// intiialize the Vecs in PatternState using with_capacity
|
||||
/// based on its knowledge of their lengths.
|
||||
pub fn constrain_pattern(
|
||||
env: &Env,
|
||||
pattern: &Pattern,
|
||||
region: Region,
|
||||
expected: PExpected<Type>,
|
||||
@ -223,14 +225,30 @@ pub fn constrain_pattern(
|
||||
));
|
||||
state.vars.push(*guard_var);
|
||||
|
||||
constrain_pattern(&loc_guard.value, loc_guard.region, expected, state);
|
||||
constrain_pattern(env, &loc_guard.value, loc_guard.region, expected, state);
|
||||
|
||||
RecordField::Required(pat_type)
|
||||
}
|
||||
DestructType::Optional(_var) => {
|
||||
todo!("Add a constraint for the default value.");
|
||||
DestructType::Optional(expr_var, loc_expr) => {
|
||||
// Eq(Type, Expected<Type>, Category, Region),
|
||||
let expr_expected = Expected::ForReason(
|
||||
Reason::RecordDefaultField(label.clone()),
|
||||
pat_type.clone(),
|
||||
loc_expr.region,
|
||||
);
|
||||
|
||||
// RecordField::Optional(pat_type)
|
||||
state.constraints.push(Constraint::Eq(
|
||||
Type::Variable(*expr_var),
|
||||
expr_expected.clone(),
|
||||
Category::DefaultValue(label.clone()),
|
||||
region,
|
||||
));
|
||||
|
||||
state.vars.push(*expr_var);
|
||||
|
||||
constrain_expr(env, loc_expr.region, &loc_expr.value, expr_expected);
|
||||
|
||||
RecordField::Optional(pat_type)
|
||||
}
|
||||
DestructType::Required => {
|
||||
// No extra constraints necessary.
|
||||
@ -283,7 +301,7 @@ pub fn constrain_pattern(
|
||||
pattern_type,
|
||||
region,
|
||||
);
|
||||
constrain_pattern(&loc_pattern.value, loc_pattern.region, expected, state);
|
||||
constrain_pattern(env, &loc_pattern.value, loc_pattern.region, expected, state);
|
||||
}
|
||||
|
||||
let whole_con = Constraint::Eq(
|
||||
|
@ -250,7 +250,7 @@ fn constrain_pattern(
|
||||
|
||||
RecordField::Required(pat_type)
|
||||
}
|
||||
DestructType::Optional(_var) => {
|
||||
DestructType::Optional(_expr_var, _loc_expr) => {
|
||||
todo!("Add a constraint for the default value.");
|
||||
|
||||
// RecordField::Optional(pat_type)
|
||||
|
@ -864,6 +864,7 @@ pub enum Reason {
|
||||
},
|
||||
RecordUpdateValue(Lowercase),
|
||||
RecordUpdateKeys(Symbol, SendMap<Lowercase, Region>),
|
||||
RecordDefaultField(Lowercase),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
@ -893,6 +894,7 @@ pub enum Category {
|
||||
Record,
|
||||
Accessor(Lowercase),
|
||||
Access(Lowercase),
|
||||
DefaultValue(Lowercase), // for setting optional fields
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
Loading…
Reference in New Issue
Block a user