mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Merge branch 'def-types-tweaks' into builtins-in-roc
This commit is contained in:
commit
6009768991
3 changed files with 44 additions and 49 deletions
|
@ -11,7 +11,7 @@ pub struct Constraints {
|
|||
pub constraints: Vec<Constraint>,
|
||||
pub types: Vec<Type>,
|
||||
pub variables: Vec<Variable>,
|
||||
pub def_types: Vec<(Symbol, Loc<Index<Type>>)>,
|
||||
pub loc_symbols: Vec<(Symbol, Region)>,
|
||||
pub let_constraints: Vec<LetConstraint>,
|
||||
pub categories: Vec<Category>,
|
||||
pub pattern_categories: Vec<PatternCategory>,
|
||||
|
@ -32,7 +32,7 @@ impl Constraints {
|
|||
let constraints = Vec::new();
|
||||
let mut types = Vec::new();
|
||||
let variables = Vec::new();
|
||||
let def_types = Vec::new();
|
||||
let loc_symbols = Vec::new();
|
||||
let let_constraints = Vec::new();
|
||||
let mut categories = Vec::with_capacity(16);
|
||||
let mut pattern_categories = Vec::with_capacity(16);
|
||||
|
@ -78,7 +78,7 @@ impl Constraints {
|
|||
constraints,
|
||||
types,
|
||||
variables,
|
||||
def_types,
|
||||
loc_symbols,
|
||||
let_constraints,
|
||||
categories,
|
||||
pattern_categories,
|
||||
|
@ -260,28 +260,33 @@ impl Constraints {
|
|||
Slice::new(start as _, length as _)
|
||||
}
|
||||
|
||||
fn def_types_slice<I>(&mut self, it: I) -> Slice<(Symbol, Loc<Index<Type>>)>
|
||||
fn def_types_slice<I>(&mut self, it: I) -> DefTypes
|
||||
where
|
||||
I: IntoIterator<Item = (Symbol, Loc<Type>)>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let it = it.into_iter();
|
||||
|
||||
let start = self.def_types.len();
|
||||
let types_start = self.types.len();
|
||||
let loc_symbols_start = self.loc_symbols.len();
|
||||
|
||||
// because we have an ExactSizeIterator, we can reserve space here
|
||||
self.def_types.reserve(it.len());
|
||||
let length = it.len();
|
||||
|
||||
self.types.reserve(length);
|
||||
self.loc_symbols.reserve(length);
|
||||
|
||||
for (symbol, loc_type) in it {
|
||||
let Loc { region, value } = loc_type;
|
||||
let type_index = Index::push_new(&mut self.types, value);
|
||||
|
||||
self.def_types.push((symbol, Loc::at(region, type_index)));
|
||||
self.types.push(value);
|
||||
self.loc_symbols.push((symbol, region));
|
||||
}
|
||||
|
||||
let length = self.def_types.len() - start;
|
||||
|
||||
Slice::new(start as _, length as _)
|
||||
DefTypes {
|
||||
types: Slice::new(types_start as _, length as _),
|
||||
loc_symbols: Slice::new(loc_symbols_start as _, length as _),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -297,7 +302,7 @@ impl Constraints {
|
|||
let let_contraint = LetConstraint {
|
||||
rigid_vars: Slice::default(),
|
||||
flex_vars: self.variable_slice(flex_vars),
|
||||
def_types: Slice::default(),
|
||||
def_types: DefTypes::default(),
|
||||
defs_and_ret_constraint,
|
||||
};
|
||||
|
||||
|
@ -323,7 +328,7 @@ impl Constraints {
|
|||
let let_contraint = LetConstraint {
|
||||
rigid_vars: Slice::default(),
|
||||
flex_vars: self.variable_slice(flex_vars),
|
||||
def_types: Slice::default(),
|
||||
def_types: DefTypes::default(),
|
||||
defs_and_ret_constraint,
|
||||
};
|
||||
|
||||
|
@ -476,11 +481,17 @@ pub enum Constraint {
|
|||
),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||
pub struct DefTypes {
|
||||
pub types: Slice<Type>,
|
||||
pub loc_symbols: Slice<(Symbol, Region)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LetConstraint {
|
||||
pub rigid_vars: Slice<Variable>,
|
||||
pub flex_vars: Slice<Variable>,
|
||||
pub def_types: Slice<(Symbol, Loc<Index<Type>>)>,
|
||||
pub def_types: DefTypes,
|
||||
pub defs_and_ret_constraint: Index<(Constraint, Constraint)>,
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ pub fn constrain_expr(
|
|||
if fields.is_empty() {
|
||||
constrain_empty_record(constraints, region, expected)
|
||||
} else {
|
||||
let mut field_exprs = SendMap::default();
|
||||
let mut field_types = SendMap::default();
|
||||
let mut field_vars = Vec::with_capacity(fields.len());
|
||||
|
||||
|
@ -115,7 +114,6 @@ pub fn constrain_expr(
|
|||
constrain_field(constraints, env, field_var, &*loc_field_expr);
|
||||
|
||||
field_vars.push(field_var);
|
||||
field_exprs.insert(label.clone(), loc_field_expr);
|
||||
field_types.insert(label.clone(), RecordField::Required(field_type));
|
||||
|
||||
rec_constraints.push(field_con);
|
||||
|
@ -1194,13 +1192,7 @@ fn constrain_when_branch(
|
|||
|
||||
// must introduce the headers from the pattern before constraining the guard
|
||||
let state_constraints = constraints.and_constraint(state.constraints);
|
||||
let inner = constraints.let_constraint(
|
||||
[],
|
||||
[],
|
||||
SendMap::default(),
|
||||
guard_constraint,
|
||||
ret_constraint,
|
||||
);
|
||||
let inner = constraints.let_constraint([], [], [], guard_constraint, ret_constraint);
|
||||
|
||||
constraints.let_constraint([], state.vars, state.headers, state_constraints, inner)
|
||||
} else {
|
||||
|
@ -1546,13 +1538,7 @@ fn constrain_def(
|
|||
);
|
||||
|
||||
let cons = [
|
||||
constraints.let_constraint(
|
||||
[],
|
||||
[],
|
||||
SendMap::default(),
|
||||
Constraint::True,
|
||||
ret_constraint,
|
||||
),
|
||||
constraints.let_constraint([], [], [], Constraint::True, ret_constraint),
|
||||
// Store type into AST vars. We use Store so errors aren't reported twice
|
||||
constraints.store(signature, expr_var, std::file!(), std::line!()),
|
||||
];
|
||||
|
@ -1605,7 +1591,7 @@ fn constrain_def_make_constraint(
|
|||
let def_con = constraints.let_constraint(
|
||||
[],
|
||||
new_infer_variables,
|
||||
SendMap::default(), // empty, because our functions have no arguments!
|
||||
[], // empty, because our functions have no arguments!
|
||||
and_constraint,
|
||||
expr_con,
|
||||
);
|
||||
|
@ -1721,6 +1707,11 @@ fn instantiate_rigids(
|
|||
annotation.substitute(&rigid_substitution);
|
||||
}
|
||||
|
||||
// TODO investigate when we can skip this. It seems to only be required for correctness
|
||||
// for recursive functions. For non-recursive functions the final type is correct, but
|
||||
// alias information is sometimes lost
|
||||
//
|
||||
// Skipping all of this cloning here would be neat!
|
||||
let loc_annotation_ref = Loc::at(loc_pattern.region, &annotation);
|
||||
if let Pattern::Identifier(symbol) = loc_pattern.value {
|
||||
headers.insert(symbol, Loc::at(loc_pattern.region, annotation.clone()));
|
||||
|
@ -1783,8 +1774,8 @@ pub fn rec_defs_help(
|
|||
// TODO investigate if this let can be safely removed
|
||||
let def_con = constraints.let_constraint(
|
||||
[],
|
||||
[], // empty because Roc function defs have no args
|
||||
SendMap::default(), // empty because Roc function defs have no args
|
||||
[], // empty because Roc function defs have no args
|
||||
[], // empty because Roc function defs have no args
|
||||
Constraint::True, // I think this is correct, once again because there are no args
|
||||
expr_con,
|
||||
);
|
||||
|
@ -1974,7 +1965,7 @@ pub fn rec_defs_help(
|
|||
rigid_info.constraints.push(constraints.let_constraint(
|
||||
new_rigid_variables,
|
||||
def_pattern_state.vars,
|
||||
SendMap::default(), // no headers introduced (at this level)
|
||||
[], // no headers introduced (at this level)
|
||||
def_con,
|
||||
Constraint::True,
|
||||
));
|
||||
|
@ -1995,7 +1986,7 @@ pub fn rec_defs_help(
|
|||
constraints.let_constraint(
|
||||
[],
|
||||
[],
|
||||
SendMap::default(),
|
||||
[],
|
||||
Constraint::True,
|
||||
ret_constraint,
|
||||
),
|
||||
|
@ -2009,7 +2000,7 @@ pub fn rec_defs_help(
|
|||
rigid_info.constraints.push(constraints.let_constraint(
|
||||
new_rigid_variables,
|
||||
def_pattern_state.vars,
|
||||
SendMap::default(), // no headers introduced (at this level)
|
||||
[], // no headers introduced (at this level)
|
||||
def_con,
|
||||
Constraint::True,
|
||||
));
|
||||
|
|
|
@ -3,7 +3,6 @@ use roc_can::constraint::Constraint::{self, *};
|
|||
use roc_can::constraint::{Constraints, LetConstraint};
|
||||
use roc_can::expected::{Expected, PExpected};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_collections::soa::{Index, Slice};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::symbol::{ModuleId, Symbol};
|
||||
use roc_region::all::{Loc, Region};
|
||||
|
@ -822,23 +821,17 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
|
|||
pools: &mut Pools,
|
||||
cached_aliases: &mut MutMap<Symbol, Variable>,
|
||||
subs: &mut Subs,
|
||||
def_types_slice: Slice<(Symbol, Loc<Index<Type>>)>,
|
||||
def_types_slice: roc_can::constraint::DefTypes,
|
||||
) -> Self {
|
||||
let def_types = &constraints.def_types[def_types_slice.indices()];
|
||||
let types_slice = &constraints.types[def_types_slice.types.indices()];
|
||||
let loc_symbols_slice = &constraints.loc_symbols[def_types_slice.loc_symbols.indices()];
|
||||
|
||||
let mut local_def_vars = Self::with_length(def_types.len());
|
||||
let mut local_def_vars = Self::with_length(types_slice.len());
|
||||
|
||||
for (symbol, loc_type_index) in def_types.iter() {
|
||||
let typ = &constraints.types[loc_type_index.value.index()];
|
||||
for ((symbol, region), typ) in loc_symbols_slice.iter().copied().zip(types_slice) {
|
||||
let var = type_to_var(subs, rank, pools, cached_aliases, typ);
|
||||
|
||||
local_def_vars.push((
|
||||
*symbol,
|
||||
Loc {
|
||||
value: var,
|
||||
region: loc_type_index.region,
|
||||
},
|
||||
));
|
||||
local_def_vars.push((symbol, Loc { value: var, region }));
|
||||
}
|
||||
|
||||
local_def_vars
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue