Merge branch 'main' into specialize-exprs

This commit is contained in:
Agus Zubiaga 2024-11-23 01:48:51 -03:00
commit 2e96aca0fd
No known key found for this signature in database
797 changed files with 17394 additions and 12632 deletions

View file

@ -18,3 +18,5 @@ roc_region = { path = "../region" }
roc_types = { path = "../types" }
arrayvec.workspace = true
soa.workspace = true

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,7 @@ fn constrain_params(
home,
rigids: MutMap::default(),
resolutions_to_make: vec![],
fx_expectation: None,
};
let index = constraints.push_variable(module_params.whole_var);
@ -114,6 +115,7 @@ fn constrain_symbols_from_requires(
home,
rigids,
resolutions_to_make: vec![],
fx_expectation: None,
};
let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(loc_symbol.value));
@ -181,6 +183,7 @@ pub fn frontload_ability_constraints(
home,
rigids,
resolutions_to_make: vec![],
fx_expectation: None,
};
let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(*member_name));

View file

@ -5,9 +5,8 @@ use roc_can::expected::{Expected, PExpected};
use roc_can::pattern::Pattern::{self, *};
use roc_can::pattern::{DestructType, ListPatterns, RecordDestruct, TupleDestruct};
use roc_collections::all::{HumanIndex, SendMap};
use roc_collections::soa::Index;
use roc_collections::VecMap;
use roc_module::ident::Lowercase;
use roc_module::ident::{IdentSuffix, Lowercase};
use roc_module::symbol::Symbol;
use roc_region::all::{Loc, Region};
use roc_types::subs::Variable;
@ -15,6 +14,7 @@ use roc_types::types::{
AliasKind, AliasShared, Category, OptAbleType, PReason, PatternCategory, Reason, RecordField,
Type, TypeExtension, TypeTag, Types,
};
use soa::Index;
#[derive(Default, Debug)]
pub struct PatternState {
@ -22,6 +22,7 @@ pub struct PatternState {
pub vars: Vec<Variable>,
pub constraints: Vec<Constraint>,
pub delayed_is_open_constraints: Vec<Constraint>,
pub delayed_fx_suffix_constraints: Vec<Constraint>,
}
/// If there is a type annotation, the pattern state headers can be optimized by putting the
@ -171,8 +172,10 @@ fn headers_from_annotation_help(
return false;
}
arguments.iter().zip(arg_types_slice.into_iter()).all(
|(arg_pattern, arg_type)| {
arguments
.iter()
.zip(arg_types_slice)
.all(|(arg_pattern, arg_type)| {
headers_from_annotation_help(
types,
constraints,
@ -180,8 +183,7 @@ fn headers_from_annotation_help(
&Loc::at(annotation.region, arg_type),
headers,
)
},
)
})
} else {
false
}
@ -246,6 +248,29 @@ pub fn constrain_pattern(
region: Region,
expected: PExpectedTypeIndex,
state: &mut PatternState,
) {
constrain_pattern_help(
types,
constraints,
env,
pattern,
region,
expected,
state,
true,
);
}
#[allow(clippy::too_many_arguments)]
pub fn constrain_pattern_help(
types: &mut Types,
constraints: &mut Constraints,
env: &mut Env,
pattern: &Pattern,
region: Region,
expected: PExpectedTypeIndex,
state: &mut PatternState,
is_shallow: bool,
) {
match pattern {
Underscore => {
@ -275,6 +300,27 @@ pub fn constrain_pattern(
.push(constraints.is_open_type(type_index));
}
// Identifiers introduced in nested patterns get let constraints
// and therefore don't need fx_pattern_suffix constraints.
if is_shallow {
match symbol.suffix() {
IdentSuffix::None => {
// Unsuffixed identifiers should be constrained after we know if they're functions
state
.delayed_fx_suffix_constraints
.push(constraints.fx_pattern_suffix(*symbol, type_index, region));
}
IdentSuffix::Bang => {
// Bang suffixed identifiers are always required to be functions
// We constrain this before the function's body,
// so that we don't think it's pure and complain about leftover statements
state
.constraints
.push(constraints.fx_pattern_suffix(*symbol, type_index, region));
}
}
}
state.headers.insert(
*symbol,
Loc {
@ -296,7 +342,7 @@ pub fn constrain_pattern(
},
);
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -304,6 +350,7 @@ pub fn constrain_pattern(
subpattern.region,
expected,
state,
false,
)
}
@ -529,7 +576,7 @@ pub fn constrain_pattern(
));
state.vars.push(*guard_var);
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -537,6 +584,7 @@ pub fn constrain_pattern(
loc_pattern.region,
expected,
state,
false,
);
pat_type
@ -627,7 +675,7 @@ pub fn constrain_pattern(
));
state.vars.push(*guard_var);
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -635,6 +683,7 @@ pub fn constrain_pattern(
loc_guard.region,
expected,
state,
false,
);
RecordField::Demanded(pat_type)
@ -750,7 +799,7 @@ pub fn constrain_pattern(
loc_pat.region,
));
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -758,6 +807,7 @@ pub fn constrain_pattern(
loc_pat.region,
expected,
state,
false,
);
}
@ -806,7 +856,7 @@ pub fn constrain_pattern(
pattern_type,
region,
));
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -814,6 +864,7 @@ pub fn constrain_pattern(
loc_pattern.region,
expected,
state,
false,
);
}
@ -871,7 +922,7 @@ pub fn constrain_pattern(
// First, add a constraint for the argument "who"
let arg_pattern_expected = constraints
.push_pat_expected_type(PExpected::NoExpectation(arg_pattern_type_index));
constrain_pattern(
constrain_pattern_help(
types,
constraints,
env,
@ -879,6 +930,7 @@ pub fn constrain_pattern(
loc_arg_pattern.region,
arg_pattern_expected,
state,
false,
);
// Next, link `whole_var` to the opaque type of "@Id who"