mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
working NQueens check
This commit is contained in:
parent
1f6e5ae74e
commit
f2fd58e223
11 changed files with 982 additions and 194 deletions
|
@ -68,6 +68,7 @@ pub fn load_types(
|
||||||
|
|
||||||
let mut types = Types::default();
|
let mut types = Types::default();
|
||||||
|
|
||||||
|
let decls = vec![];
|
||||||
for decl in decls.into_iter() {
|
for decl in decls.into_iter() {
|
||||||
let defs = match decl {
|
let defs = match decl {
|
||||||
Declaration::Declare(def) => {
|
Declaration::Declare(def) => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::annotation::OwnedNamedOrAble;
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
use crate::expr::AnnotatedMark;
|
use crate::expr::AnnotatedMark;
|
||||||
use crate::expr::ClosureData;
|
use crate::expr::ClosureData;
|
||||||
|
use crate::expr::Declarations;
|
||||||
use crate::expr::Expr::{self, *};
|
use crate::expr::Expr::{self, *};
|
||||||
use crate::expr::{canonicalize_expr, Output, Recursive};
|
use crate::expr::{canonicalize_expr, Output, Recursive};
|
||||||
use crate::pattern::{canonicalize_def_header_pattern, BindingsFromPattern, Pattern};
|
use crate::pattern::{canonicalize_def_header_pattern, BindingsFromPattern, Pattern};
|
||||||
|
@ -745,6 +746,108 @@ impl DefOrdering {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn sort_can_defs_new(
|
||||||
|
env: &mut Env<'_>,
|
||||||
|
defs: CanDefs,
|
||||||
|
mut output: Output,
|
||||||
|
) -> (Declarations, Output) {
|
||||||
|
let CanDefs {
|
||||||
|
defs,
|
||||||
|
def_ordering,
|
||||||
|
aliases,
|
||||||
|
abilities_in_scope,
|
||||||
|
} = defs;
|
||||||
|
|
||||||
|
// TODO: inefficient, but I want to make this what CanDefs contains in the future
|
||||||
|
let mut defs: Vec<_> = defs.into_iter().map(|x| x.unwrap()).collect();
|
||||||
|
|
||||||
|
let mut declarations = Declarations::with_capacity(defs.len());
|
||||||
|
|
||||||
|
output.abilities_in_scope = abilities_in_scope;
|
||||||
|
|
||||||
|
for (symbol, alias) in aliases.into_iter() {
|
||||||
|
output.aliases.insert(symbol, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We first perform SCC based on any reference, both variable usage and calls
|
||||||
|
// considering both value definitions and function bodies. This will spot any
|
||||||
|
// recursive relations between any 2 definitions.
|
||||||
|
let sccs = def_ordering.references.strongly_connected_components_all();
|
||||||
|
|
||||||
|
sccs.reorder(&mut defs);
|
||||||
|
|
||||||
|
for group in sccs.groups().rev() {
|
||||||
|
match group.count_ones() {
|
||||||
|
1 => {
|
||||||
|
// a group with a single Def, nice and simple
|
||||||
|
let def = defs.pop().unwrap();
|
||||||
|
let index = group.first_one().unwrap();
|
||||||
|
|
||||||
|
if def_ordering.direct_references.get_row_col(index, index) {
|
||||||
|
// a definition like `x = x + 1`, which is invalid in roc
|
||||||
|
let symbol = def_ordering.get_symbol(index).unwrap();
|
||||||
|
|
||||||
|
let entries = vec![make_cycle_entry(symbol, &def)];
|
||||||
|
|
||||||
|
let problem = Problem::RuntimeError(RuntimeError::CircularDef(entries.clone()));
|
||||||
|
env.problem(problem);
|
||||||
|
|
||||||
|
// Declaration::InvalidCycle(entries)
|
||||||
|
todo!("InvalidCycle: {:?}", entries)
|
||||||
|
} else if def_ordering.references.get_row_col(index, index) {
|
||||||
|
// this function calls itself, and must be typechecked as a recursive def
|
||||||
|
match def.loc_pattern.value {
|
||||||
|
Pattern::Identifier(symbol) => match def.loc_expr.value {
|
||||||
|
Closure(closure_data) => {
|
||||||
|
declarations.push_recursive_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
Loc::at(def.loc_expr.region, closure_data),
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => todo!(),
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Declaration::Declare(def)
|
||||||
|
match def.loc_pattern.value {
|
||||||
|
Pattern::Identifier(symbol) => match def.loc_expr.value {
|
||||||
|
Closure(closure_data) => {
|
||||||
|
declarations.push_function_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
Loc::at(def.loc_expr.region, closure_data),
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
declarations.push_value_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
def.loc_expr,
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
group_length => {
|
||||||
|
let group_defs = defs.split_off(defs.len() - group_length);
|
||||||
|
|
||||||
|
dbg!(&group_defs);
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(declarations, output)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn sort_can_defs(
|
pub(crate) fn sort_can_defs(
|
||||||
env: &mut Env<'_>,
|
env: &mut Env<'_>,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::annotation::IntroducedVariables;
|
use crate::annotation::IntroducedVariables;
|
||||||
use crate::def::{Declaration, Def};
|
use crate::def::{Declaration, Def};
|
||||||
use crate::expr::{AnnotatedMark, ClosureData, Expr, Recursive};
|
use crate::expr::{AnnotatedMark, ClosureData, Declarations, Expr, Recursive};
|
||||||
use crate::pattern::Pattern;
|
use crate::pattern::Pattern;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use roc_collections::{SendMap, VecSet};
|
use roc_collections::{SendMap, VecSet};
|
||||||
|
@ -38,7 +38,7 @@ pub(crate) fn build_effect_builtins(
|
||||||
effect_symbol: Symbol,
|
effect_symbol: Symbol,
|
||||||
var_store: &mut VarStore,
|
var_store: &mut VarStore,
|
||||||
exposed_symbols: &mut VecSet<Symbol>,
|
exposed_symbols: &mut VecSet<Symbol>,
|
||||||
declarations: &mut Vec<Declaration>,
|
declarations: &mut Declarations,
|
||||||
generated_functions: HostedGeneratedFunctions,
|
generated_functions: HostedGeneratedFunctions,
|
||||||
) {
|
) {
|
||||||
macro_rules! helper {
|
macro_rules! helper {
|
||||||
|
@ -54,31 +54,31 @@ pub(crate) fn build_effect_builtins(
|
||||||
|
|
||||||
if generated_functions.after {
|
if generated_functions.after {
|
||||||
let def = helper!(build_effect_after);
|
let def = helper!(build_effect_after);
|
||||||
declarations.push(Declaration::Declare(def));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect.map : Effect a, (a -> b) -> Effect b
|
// Effect.map : Effect a, (a -> b) -> Effect b
|
||||||
if generated_functions.map {
|
if generated_functions.map {
|
||||||
let def = helper!(build_effect_map);
|
let def = helper!(build_effect_map);
|
||||||
declarations.push(Declaration::Declare(def));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect.always : a -> Effect a
|
// Effect.always : a -> Effect a
|
||||||
if generated_functions.always {
|
if generated_functions.always {
|
||||||
let def = helper!(build_effect_always);
|
let def = helper!(build_effect_always);
|
||||||
declarations.push(Declaration::Declare(def));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect.forever : Effect a -> Effect b
|
// Effect.forever : Effect a -> Effect b
|
||||||
if generated_functions.forever {
|
if generated_functions.forever {
|
||||||
let def = helper!(build_effect_forever);
|
let def = helper!(build_effect_forever);
|
||||||
declarations.push(Declaration::DeclareRec(vec![def]));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect.loop : a, (a -> Effect [ Step a, Done b ]) -> Effect b
|
// Effect.loop : a, (a -> Effect [ Step a, Done b ]) -> Effect b
|
||||||
if generated_functions.loop_ {
|
if generated_functions.loop_ {
|
||||||
let def = helper!(build_effect_loop);
|
let def = helper!(build_effect_loop);
|
||||||
declarations.push(Declaration::DeclareRec(vec![def]));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useful when working on functions in this module. By default symbols that we named do now
|
// Useful when working on functions in this module. By default symbols that we named do now
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::abilities::SpecializationId;
|
use crate::abilities::SpecializationId;
|
||||||
use crate::annotation::{freshen_opaque_def, IntroducedVariables};
|
use crate::annotation::{freshen_opaque_def, IntroducedVariables};
|
||||||
use crate::builtins::builtin_defs_map;
|
use crate::builtins::builtin_defs_map;
|
||||||
use crate::def::{can_defs_with_return, Def};
|
use crate::def::{can_defs_with_return, Annotation, Def};
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
use crate::num::{
|
use crate::num::{
|
||||||
finish_parsing_base, finish_parsing_float, finish_parsing_num, float_expr_from_result,
|
finish_parsing_base, finish_parsing_float, finish_parsing_num, float_expr_from_result,
|
||||||
|
@ -1924,34 +1924,244 @@ pub struct Declarations {
|
||||||
pub destructs: Vec<DestructureDef>,
|
pub destructs: Vec<DestructureDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Declarations {
|
impl Default for Declarations {
|
||||||
pub fn len(&self) -> usize {
|
fn default() -> Self {
|
||||||
let mut accum = 0;
|
Self::new()
|
||||||
for tag in self.declarations.iter() {
|
|
||||||
match tag {
|
|
||||||
DeclarationTag::Function(_) => accum += 1,
|
|
||||||
DeclarationTag::Value => accum += 1,
|
|
||||||
DeclarationTag::Destructure(_) => accum += 1,
|
|
||||||
DeclarationTag::MutualRecursion(slice) => accum += slice.len(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accum
|
impl Declarations {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::with_capacity(0)
|
||||||
|
}
|
||||||
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
declarations: Vec::with_capacity(capacity),
|
||||||
|
variables: Vec::with_capacity(capacity),
|
||||||
|
symbols: Vec::with_capacity(capacity),
|
||||||
|
annotations: Vec::with_capacity(capacity),
|
||||||
|
function_bodies: Vec::with_capacity(capacity),
|
||||||
|
expressions: Vec::with_capacity(capacity),
|
||||||
|
destructs: Vec::new(), // number of destructs is probably low
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_recursive_def(
|
||||||
|
&mut self,
|
||||||
|
symbol: Loc<Symbol>,
|
||||||
|
loc_closure_data: Loc<ClosureData>,
|
||||||
|
expr_var: Variable,
|
||||||
|
annotation: Option<Annotation>,
|
||||||
|
) -> usize {
|
||||||
|
let index = self.declarations.len();
|
||||||
|
|
||||||
|
let function_def = FunctionDef {
|
||||||
|
closure_type: loc_closure_data.value.closure_type,
|
||||||
|
closure_ext_var: loc_closure_data.value.closure_ext_var,
|
||||||
|
return_type: loc_closure_data.value.return_type,
|
||||||
|
captured_symbols: loc_closure_data.value.captured_symbols,
|
||||||
|
arguments: loc_closure_data.value.arguments,
|
||||||
|
};
|
||||||
|
|
||||||
|
let loc_function_def = Loc::at(loc_closure_data.region, function_def);
|
||||||
|
|
||||||
|
let function_def_index = Index::push_new(&mut self.function_bodies, loc_function_def);
|
||||||
|
|
||||||
|
let tag = match loc_closure_data.value.recursive {
|
||||||
|
Recursive::NotRecursive | Recursive::Recursive => {
|
||||||
|
DeclarationTag::Recursive(function_def_index)
|
||||||
|
}
|
||||||
|
Recursive::TailRecursive => DeclarationTag::TailRecursive(function_def_index),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.declarations.push(tag);
|
||||||
|
self.variables.push(expr_var);
|
||||||
|
self.symbols.push(symbol);
|
||||||
|
self.annotations.push(annotation);
|
||||||
|
|
||||||
|
self.expressions.push(*loc_closure_data.value.loc_body);
|
||||||
|
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_function_def(
|
||||||
|
&mut self,
|
||||||
|
symbol: Loc<Symbol>,
|
||||||
|
loc_closure_data: Loc<ClosureData>,
|
||||||
|
expr_var: Variable,
|
||||||
|
annotation: Option<Annotation>,
|
||||||
|
) -> usize {
|
||||||
|
let index = self.declarations.len();
|
||||||
|
|
||||||
|
let function_def = FunctionDef {
|
||||||
|
closure_type: loc_closure_data.value.closure_type,
|
||||||
|
closure_ext_var: loc_closure_data.value.closure_ext_var,
|
||||||
|
return_type: loc_closure_data.value.return_type,
|
||||||
|
captured_symbols: loc_closure_data.value.captured_symbols,
|
||||||
|
arguments: loc_closure_data.value.arguments,
|
||||||
|
};
|
||||||
|
|
||||||
|
let loc_function_def = Loc::at(loc_closure_data.region, function_def);
|
||||||
|
|
||||||
|
let function_def_index = Index::push_new(&mut self.function_bodies, loc_function_def);
|
||||||
|
|
||||||
|
self.declarations
|
||||||
|
.push(DeclarationTag::Function(function_def_index));
|
||||||
|
self.variables.push(expr_var);
|
||||||
|
self.symbols.push(symbol);
|
||||||
|
self.annotations.push(annotation);
|
||||||
|
|
||||||
|
self.expressions.push(*loc_closure_data.value.loc_body);
|
||||||
|
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_value_def(
|
||||||
|
&mut self,
|
||||||
|
symbol: Loc<Symbol>,
|
||||||
|
loc_expr: Loc<Expr>,
|
||||||
|
expr_var: Variable,
|
||||||
|
annotation: Option<Annotation>,
|
||||||
|
) -> usize {
|
||||||
|
let index = self.declarations.len();
|
||||||
|
|
||||||
|
self.declarations.push(DeclarationTag::Value);
|
||||||
|
self.variables.push(expr_var);
|
||||||
|
self.symbols.push(symbol);
|
||||||
|
self.annotations.push(annotation);
|
||||||
|
|
||||||
|
self.expressions.push(loc_expr);
|
||||||
|
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_def(&mut self, def: Def) {
|
||||||
|
match def.loc_pattern.value {
|
||||||
|
Pattern::Identifier(symbol) => match def.loc_expr.value {
|
||||||
|
Expr::Closure(closure_data) => match closure_data.recursive {
|
||||||
|
Recursive::NotRecursive => {
|
||||||
|
self.push_function_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
Loc::at(def.loc_expr.region, closure_data),
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Recursive::Recursive | Recursive::TailRecursive => {
|
||||||
|
self.push_recursive_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
Loc::at(def.loc_expr.region, closure_data),
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
self.push_value_def(
|
||||||
|
Loc::at(def.loc_pattern.region, symbol),
|
||||||
|
def.loc_expr,
|
||||||
|
def.expr_var,
|
||||||
|
def.annotation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_builtin_def(&mut self, index: usize, def: Def) {
|
||||||
|
match def.loc_pattern.value {
|
||||||
|
Pattern::Identifier(s) => assert_eq!(s, self.symbols[index].value),
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
match def.loc_expr.value {
|
||||||
|
Expr::Closure(closure_data) => {
|
||||||
|
let function_def = FunctionDef {
|
||||||
|
closure_type: closure_data.closure_type,
|
||||||
|
closure_ext_var: closure_data.closure_ext_var,
|
||||||
|
return_type: closure_data.return_type,
|
||||||
|
captured_symbols: closure_data.captured_symbols,
|
||||||
|
arguments: closure_data.arguments,
|
||||||
|
};
|
||||||
|
|
||||||
|
let loc_function_def = Loc::at(def.loc_expr.region, function_def);
|
||||||
|
|
||||||
|
let function_def_index =
|
||||||
|
Index::push_new(&mut self.function_bodies, loc_function_def);
|
||||||
|
|
||||||
|
self.declarations[index] = DeclarationTag::Function(function_def_index);
|
||||||
|
self.expressions[index] = *closure_data.loc_body;
|
||||||
|
|
||||||
|
// TODO investigate whether this matters, and if we can be more efficient here
|
||||||
|
self.variables[index] = def.expr_var;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.declarations[index] = DeclarationTag::Value;
|
||||||
|
self.expressions[index] = def.loc_expr;
|
||||||
|
|
||||||
|
// TODO investigate whether this matters, and if we can be more efficient here
|
||||||
|
self.variables[index] = def.expr_var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.declarations.iter().map(|d| d.len()).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_top_down(&self) -> impl Iterator<Item = (usize, DeclarationTag)> + '_ {
|
||||||
|
self.declarations.iter().scan(0, |state, e| {
|
||||||
|
let length_so_far = *state;
|
||||||
|
|
||||||
|
*state += e.len();
|
||||||
|
|
||||||
|
Some((length_so_far, *e))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_bottom_up(&self) -> impl Iterator<Item = (usize, DeclarationTag)> + '_ {
|
||||||
|
self.declarations
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.scan(self.declarations.len() - 1, |state, e| {
|
||||||
|
let length_so_far = *state;
|
||||||
|
|
||||||
|
*state = length_so_far.saturating_sub(e.len());
|
||||||
|
|
||||||
|
Some((length_so_far, *e))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum DeclarationTag {
|
pub enum DeclarationTag {
|
||||||
Value,
|
Value,
|
||||||
Function(Index<Loc<FunctionDef>>),
|
Function(Index<Loc<FunctionDef>>),
|
||||||
|
Recursive(Index<Loc<FunctionDef>>),
|
||||||
|
TailRecursive(Index<Loc<FunctionDef>>),
|
||||||
Destructure(Index<DestructureDef>),
|
Destructure(Index<DestructureDef>),
|
||||||
MutualRecursion(Slice<FunctionDef>),
|
MutualRecursion(Slice<FunctionDef>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DeclarationTag {
|
||||||
|
fn len(self) -> usize {
|
||||||
|
match self {
|
||||||
|
DeclarationTag::Function(_) => 1,
|
||||||
|
DeclarationTag::Recursive(_) => 1,
|
||||||
|
DeclarationTag::TailRecursive(_) => 1,
|
||||||
|
DeclarationTag::Value => 1,
|
||||||
|
DeclarationTag::Destructure(_) => 1,
|
||||||
|
DeclarationTag::MutualRecursion(slice) => slice.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct FunctionDef {
|
pub struct FunctionDef {
|
||||||
pub closure_type: Variable,
|
pub closure_type: Variable,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::abilities::AbilitiesStore;
|
use crate::abilities::AbilitiesStore;
|
||||||
use crate::annotation::canonicalize_annotation;
|
use crate::annotation::canonicalize_annotation;
|
||||||
use crate::def::{canonicalize_defs, sort_can_defs, Declaration, Def};
|
use crate::def::{canonicalize_defs, Def};
|
||||||
use crate::effect_module::HostedGeneratedFunctions;
|
use crate::effect_module::HostedGeneratedFunctions;
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
use crate::expr::{ClosureData, Expr, Output};
|
use crate::expr::{ClosureData, Declarations, Expr, Output};
|
||||||
use crate::operator::desugar_def;
|
use crate::operator::desugar_def;
|
||||||
use crate::pattern::Pattern;
|
use crate::pattern::Pattern;
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
|
@ -44,7 +44,7 @@ pub struct RigidVariables {
|
||||||
pub struct ModuleOutput {
|
pub struct ModuleOutput {
|
||||||
pub aliases: MutMap<Symbol, Alias>,
|
pub aliases: MutMap<Symbol, Alias>,
|
||||||
pub rigid_variables: RigidVariables,
|
pub rigid_variables: RigidVariables,
|
||||||
pub declarations: Vec<Declaration>,
|
pub declarations: Declarations,
|
||||||
pub exposed_imports: MutMap<Symbol, Variable>,
|
pub exposed_imports: MutMap<Symbol, Variable>,
|
||||||
pub lookups: Vec<(Symbol, Variable, Region)>,
|
pub lookups: Vec<(Symbol, Variable, Region)>,
|
||||||
pub problems: Vec<Problem>,
|
pub problems: Vec<Problem>,
|
||||||
|
@ -351,7 +351,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut declarations, mut output) = sort_can_defs(&mut env, defs, new_output);
|
let (mut declarations, mut output) = crate::def::sort_can_defs_new(&mut env, defs, new_output);
|
||||||
|
|
||||||
let symbols_from_requires = symbols_from_requires
|
let symbols_from_requires = symbols_from_requires
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -399,40 +399,39 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::def::Declaration::*;
|
let mut index = 0;
|
||||||
for decl in declarations.iter_mut() {
|
while index < declarations.len() {
|
||||||
match decl {
|
use crate::expr::DeclarationTag::*;
|
||||||
Declare(def) => {
|
|
||||||
for (symbol, _) in def.pattern_vars.iter() {
|
let tag = declarations.declarations[index];
|
||||||
if exposed_but_not_defined.contains(symbol) {
|
|
||||||
|
match tag {
|
||||||
|
Value => {
|
||||||
|
let symbol = &declarations.symbols[index].value;
|
||||||
|
|
||||||
// Remove this from exposed_symbols,
|
// Remove this from exposed_symbols,
|
||||||
// so that at the end of the process,
|
// so that at the end of the process,
|
||||||
// we can see if there were any
|
// we can see if there were any
|
||||||
// exposed symbols which did not have
|
// exposed symbols which did not have
|
||||||
// corresponding defs.
|
// corresponding defs.
|
||||||
exposed_but_not_defined.remove(symbol);
|
exposed_but_not_defined.remove(symbol);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporary hack: we don't know exactly what symbols are hosted symbols,
|
// Temporary hack: we don't know exactly what symbols are hosted symbols,
|
||||||
// and which are meant to be normal definitions without a body. So for now
|
// and which are meant to be normal definitions without a body. So for now
|
||||||
// we just assume they are hosted functions (meant to be provided by the platform)
|
// we just assume they are hosted functions (meant to be provided by the platform)
|
||||||
if has_no_implementation(&def.loc_expr.value) {
|
if has_no_implementation(&declarations.expressions[index].value) {
|
||||||
match generated_info {
|
match generated_info {
|
||||||
GeneratedInfo::Builtin => {
|
GeneratedInfo::Builtin => {
|
||||||
let symbol = def.pattern_vars.iter().next().unwrap().0;
|
|
||||||
match crate::builtins::builtin_defs_map(*symbol, var_store) {
|
match crate::builtins::builtin_defs_map(*symbol, var_store) {
|
||||||
None => {
|
None => {
|
||||||
panic!("A builtin module contains a signature without implementation for {:?}", symbol)
|
panic!("A builtin module contains a signature without implementation for {:?}", symbol)
|
||||||
}
|
}
|
||||||
Some(mut replacement_def) => {
|
Some(replacement_def) => {
|
||||||
replacement_def.annotation = def.annotation.take();
|
declarations.update_builtin_def(index, replacement_def);
|
||||||
*def = replacement_def;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GeneratedInfo::Hosted { effect_symbol, .. } => {
|
GeneratedInfo::Hosted { effect_symbol, .. } => {
|
||||||
let symbol = def.pattern_vars.iter().next().unwrap().0;
|
|
||||||
let ident_id = symbol.ident_id();
|
let ident_id = symbol.ident_id();
|
||||||
let ident = scope
|
let ident = scope
|
||||||
.locals
|
.locals
|
||||||
|
@ -440,7 +439,9 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
.get_name(ident_id)
|
.get_name(ident_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
let def_annotation = def.annotation.clone().unwrap();
|
|
||||||
|
let def_annotation = declarations.annotations[index].clone().unwrap();
|
||||||
|
|
||||||
let annotation = crate::annotation::Annotation {
|
let annotation = crate::annotation::Annotation {
|
||||||
typ: def_annotation.signature,
|
typ: def_annotation.signature,
|
||||||
introduced_variables: def_annotation.introduced_variables,
|
introduced_variables: def_annotation.introduced_variables,
|
||||||
|
@ -457,38 +458,28 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
annotation,
|
annotation,
|
||||||
);
|
);
|
||||||
|
|
||||||
*def = hosted_def;
|
declarations.update_builtin_def(index, hosted_def);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index += 1;
|
||||||
}
|
}
|
||||||
DeclareRec(defs) => {
|
Function(_) | Recursive(_) | TailRecursive(_) => {
|
||||||
for def in defs {
|
let symbol = &declarations.symbols[index].value;
|
||||||
for (symbol, _) in def.pattern_vars.iter() {
|
|
||||||
if exposed_but_not_defined.contains(symbol) {
|
|
||||||
// Remove this from exposed_symbols,
|
// Remove this from exposed_symbols,
|
||||||
// so that at the end of the process,
|
// so that at the end of the process,
|
||||||
// we can see if there were any
|
// we can see if there were any
|
||||||
// exposed symbols which did not have
|
// exposed symbols which did not have
|
||||||
// corresponding defs.
|
// corresponding defs.
|
||||||
exposed_but_not_defined.remove(symbol);
|
exposed_but_not_defined.remove(symbol);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidCycle(entries) => {
|
index += 1;
|
||||||
env.problems.push(Problem::BadRecursion(entries.to_vec()));
|
|
||||||
}
|
|
||||||
Builtin(def) => {
|
|
||||||
// Builtins cannot be exposed in module declarations.
|
|
||||||
// This should never happen!
|
|
||||||
debug_assert!(def
|
|
||||||
.pattern_vars
|
|
||||||
.iter()
|
|
||||||
.all(|(symbol, _)| !exposed_but_not_defined.contains(symbol)));
|
|
||||||
}
|
}
|
||||||
|
Destructure(_) => todo!(),
|
||||||
|
MutualRecursion(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,7 +533,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
annotation: None,
|
annotation: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
declarations.push(Declaration::Declare(def));
|
declarations.push_def(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incorporate any remaining output.lookups entries into references.
|
// Incorporate any remaining output.lookups entries into references.
|
||||||
|
@ -556,13 +547,14 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
referenced_values.extend(env.qualified_value_lookups.iter().copied());
|
referenced_values.extend(env.qualified_value_lookups.iter().copied());
|
||||||
referenced_types.extend(env.qualified_type_lookups.iter().copied());
|
referenced_types.extend(env.qualified_type_lookups.iter().copied());
|
||||||
|
|
||||||
for declaration in declarations.iter_mut() {
|
// TODO
|
||||||
match declaration {
|
// for declaration in declarations.iter_mut() {
|
||||||
Declare(def) => fix_values_captured_in_closure_def(def, &mut VecSet::default()),
|
// match declaration {
|
||||||
DeclareRec(defs) => fix_values_captured_in_closure_defs(defs, &mut VecSet::default()),
|
// Declare(def) => fix_values_captured_in_closure_def(def, &mut VecSet::default()),
|
||||||
InvalidCycle(_) | Builtin(_) => {}
|
// DeclareRec(defs) => fix_values_captured_in_closure_defs(defs, &mut VecSet::default()),
|
||||||
}
|
// InvalidCycle(_) | Builtin(_) => {}
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
ModuleOutput {
|
ModuleOutput {
|
||||||
scope,
|
scope,
|
||||||
|
|
|
@ -99,6 +99,10 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
||||||
visitor.visit_def(def);
|
visitor.visit_def(def);
|
||||||
visitor.visit_expr(&body.value, body.region, var);
|
visitor.visit_expr(&body.value, body.region, var);
|
||||||
}
|
}
|
||||||
|
Expr::LetBlock(declarations, body) => {
|
||||||
|
todo!("visit {:?}", declarations);
|
||||||
|
visitor.visit_expr(&body.value, body.region, var);
|
||||||
|
}
|
||||||
Expr::Call(f, args, _called_via) => {
|
Expr::Call(f, args, _called_via) => {
|
||||||
let (fn_var, loc_fn, _closure_var, _ret_var) = &**f;
|
let (fn_var, loc_fn, _closure_var, _ret_var) = &**f;
|
||||||
walk_call(visitor, *fn_var, loc_fn, args);
|
walk_call(visitor, *fn_var, loc_fn, args);
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl<T> Index<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn index(&self) -> usize {
|
pub const fn index(self) -> usize {
|
||||||
self.index as usize
|
self.index as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@ impl<T> Index<T> {
|
||||||
|
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn as_slice(self) -> Slice<T> {
|
||||||
|
Slice::new(self.index, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
|
|
|
@ -9,9 +9,12 @@ use roc_can::exhaustive::{sketch_pattern_to_rows, sketch_when_branches, Exhausti
|
||||||
use roc_can::expected::Expected::{self, *};
|
use roc_can::expected::Expected::{self, *};
|
||||||
use roc_can::expected::PExpected;
|
use roc_can::expected::PExpected;
|
||||||
use roc_can::expr::Expr::{self, *};
|
use roc_can::expr::Expr::{self, *};
|
||||||
use roc_can::expr::{AccessorData, AnnotatedMark, ClosureData, Field, WhenBranch};
|
use roc_can::expr::{
|
||||||
|
AccessorData, AnnotatedMark, ClosureData, Declarations, Field, FunctionDef, WhenBranch,
|
||||||
|
};
|
||||||
use roc_can::pattern::Pattern;
|
use roc_can::pattern::Pattern;
|
||||||
use roc_collections::all::{HumanIndex, MutMap, SendMap};
|
use roc_collections::all::{HumanIndex, MutMap, SendMap};
|
||||||
|
use roc_collections::soa::{Index, Slice};
|
||||||
use roc_module::ident::{Lowercase, TagName};
|
use roc_module::ident::{Lowercase, TagName};
|
||||||
use roc_module::symbol::{ModuleId, Symbol};
|
use roc_module::symbol::{ModuleId, Symbol};
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region};
|
||||||
|
@ -87,7 +90,7 @@ fn constrain_untyped_args(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn constrain_closure(
|
fn constrain_untyped_closure(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
env: &Env,
|
env: &Env,
|
||||||
region: Region,
|
region: Region,
|
||||||
|
@ -432,7 +435,7 @@ pub fn constrain_expr(
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
// shared code with function defs without an annotation
|
// shared code with function defs without an annotation
|
||||||
constrain_closure(
|
constrain_untyped_closure(
|
||||||
constraints,
|
constraints,
|
||||||
env,
|
env,
|
||||||
region,
|
region,
|
||||||
|
@ -936,98 +939,8 @@ pub fn constrain_expr(
|
||||||
loop {
|
loop {
|
||||||
match declarations.declarations[index] {
|
match declarations.declarations[index] {
|
||||||
roc_can::expr::DeclarationTag::Value => {
|
roc_can::expr::DeclarationTag::Value => {
|
||||||
let loc_expr = &declarations.expressions[index];
|
body_con =
|
||||||
let loc_symbol = declarations.symbols[index];
|
constrain_value_def(constraints, env, declarations, index, body_con);
|
||||||
let expr_var = declarations.variables[index];
|
|
||||||
let opt_annotation = &declarations.annotations[index];
|
|
||||||
|
|
||||||
match opt_annotation {
|
|
||||||
Some(annotation) => {
|
|
||||||
let arity = 1;
|
|
||||||
let rigids = &env.rigids;
|
|
||||||
let mut ftv = rigids.clone();
|
|
||||||
|
|
||||||
let InstantiateRigids {
|
|
||||||
signature,
|
|
||||||
new_rigid_variables,
|
|
||||||
new_infer_variables,
|
|
||||||
} = instantiate_rigids_simple(
|
|
||||||
&annotation.signature,
|
|
||||||
&annotation.introduced_variables,
|
|
||||||
&mut ftv,
|
|
||||||
);
|
|
||||||
|
|
||||||
let loc_pattern = Loc::at(
|
|
||||||
loc_symbol.region,
|
|
||||||
Pattern::Identifier(loc_symbol.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
let annotation_expected = FromAnnotation(
|
|
||||||
loc_pattern,
|
|
||||||
arity,
|
|
||||||
AnnotationSource::TypedBody {
|
|
||||||
region: annotation.region,
|
|
||||||
},
|
|
||||||
signature.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO missing equality of annotation_expected with expr_var?
|
|
||||||
// but the signature is stored into the expr_var below?!
|
|
||||||
|
|
||||||
let ret_constraint = constrain_expr(
|
|
||||||
constraints,
|
|
||||||
env,
|
|
||||||
loc_expr.region,
|
|
||||||
&loc_expr.value,
|
|
||||||
annotation_expected,
|
|
||||||
);
|
|
||||||
|
|
||||||
let cons = [
|
|
||||||
ret_constraint,
|
|
||||||
// Store type into AST vars. We use Store so errors aren't reported twice
|
|
||||||
constraints.store(
|
|
||||||
signature.clone(),
|
|
||||||
expr_var,
|
|
||||||
std::file!(),
|
|
||||||
std::line!(),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
let expr_con = constraints.and_constraint(cons);
|
|
||||||
|
|
||||||
body_con = constrain_def_make_constraint_simple(
|
|
||||||
constraints,
|
|
||||||
new_rigid_variables,
|
|
||||||
new_infer_variables,
|
|
||||||
expr_con,
|
|
||||||
body_con,
|
|
||||||
loc_symbol,
|
|
||||||
expr_var,
|
|
||||||
signature,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let expr_type = Type::Variable(expr_var);
|
|
||||||
|
|
||||||
let expr_con = constrain_expr(
|
|
||||||
constraints,
|
|
||||||
env,
|
|
||||||
loc_expr.region,
|
|
||||||
&loc_expr.value,
|
|
||||||
NoExpectation(expr_type),
|
|
||||||
);
|
|
||||||
|
|
||||||
body_con = constrain_def_make_constraint_simple(
|
|
||||||
constraints,
|
|
||||||
vec![],
|
|
||||||
vec![],
|
|
||||||
expr_con,
|
|
||||||
body_con,
|
|
||||||
loc_symbol,
|
|
||||||
expr_var,
|
|
||||||
Type::Variable(expr_var),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
break;
|
break;
|
||||||
|
@ -1035,6 +948,7 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
index -= 1;
|
index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
roc_can::expr::DeclarationTag::Function(function_def_index) => {
|
roc_can::expr::DeclarationTag::Function(function_def_index) => {
|
||||||
let loc_expr = &declarations.expressions[index];
|
let loc_expr = &declarations.expressions[index];
|
||||||
let loc_symbol = declarations.symbols[index];
|
let loc_symbol = declarations.symbols[index];
|
||||||
|
@ -1210,7 +1124,7 @@ pub fn constrain_expr(
|
||||||
None => {
|
None => {
|
||||||
let expr_type = Type::Variable(expr_var);
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
|
||||||
let expr_con = constrain_closure(
|
let expr_con = constrain_untyped_closure(
|
||||||
constraints,
|
constraints,
|
||||||
env,
|
env,
|
||||||
loc_function_def.region,
|
loc_function_def.region,
|
||||||
|
@ -1246,6 +1160,8 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
roc_can::expr::DeclarationTag::Destructure(_) => todo!(),
|
roc_can::expr::DeclarationTag::Destructure(_) => todo!(),
|
||||||
roc_can::expr::DeclarationTag::MutualRecursion(_) => todo!(),
|
roc_can::expr::DeclarationTag::MutualRecursion(_) => todo!(),
|
||||||
|
roc_can::expr::DeclarationTag::Recursive(_) => todo!(),
|
||||||
|
roc_can::expr::DeclarationTag::TailRecursive(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1493,6 +1409,288 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constrain_function_def(
|
||||||
|
constraints: &mut Constraints,
|
||||||
|
env: &Env,
|
||||||
|
declarations: &Declarations,
|
||||||
|
index: usize,
|
||||||
|
function_def_index: Index<Loc<FunctionDef>>,
|
||||||
|
body_con: Constraint,
|
||||||
|
) -> Constraint {
|
||||||
|
let loc_expr = &declarations.expressions[index];
|
||||||
|
let loc_symbol = declarations.symbols[index];
|
||||||
|
let expr_var = declarations.variables[index];
|
||||||
|
let opt_annotation = &declarations.annotations[index];
|
||||||
|
|
||||||
|
let loc_function_def = &declarations.function_bodies[function_def_index.index()];
|
||||||
|
let function_def = &loc_function_def.value;
|
||||||
|
|
||||||
|
match opt_annotation {
|
||||||
|
Some(annotation) => {
|
||||||
|
let arity = annotation.signature.arity();
|
||||||
|
let rigids = &env.rigids;
|
||||||
|
let mut ftv = rigids.clone();
|
||||||
|
|
||||||
|
let InstantiateRigids {
|
||||||
|
signature,
|
||||||
|
new_rigid_variables,
|
||||||
|
new_infer_variables,
|
||||||
|
} = instantiate_rigids_simple(
|
||||||
|
&annotation.signature,
|
||||||
|
&annotation.introduced_variables,
|
||||||
|
&mut ftv,
|
||||||
|
);
|
||||||
|
|
||||||
|
let loc_pattern = Loc::at(loc_symbol.region, Pattern::Identifier(loc_symbol.value));
|
||||||
|
|
||||||
|
// TODO missing equality of annotation_expected with expr_var?
|
||||||
|
// but the signature is stored into the expr_var below?!
|
||||||
|
|
||||||
|
let region = loc_function_def.region;
|
||||||
|
|
||||||
|
let loc_body_expr = loc_expr;
|
||||||
|
let mut argument_pattern_state = PatternState {
|
||||||
|
headers: SendMap::default(),
|
||||||
|
vars: Vec::with_capacity(function_def.arguments.len()),
|
||||||
|
constraints: Vec::with_capacity(1),
|
||||||
|
delayed_is_open_constraints: vec![],
|
||||||
|
};
|
||||||
|
let mut vars = Vec::with_capacity(argument_pattern_state.vars.capacity() + 1);
|
||||||
|
let ret_var = function_def.return_type;
|
||||||
|
let closure_var = function_def.closure_type;
|
||||||
|
let closure_ext_var = function_def.closure_ext_var;
|
||||||
|
|
||||||
|
let (arg_types, signature_closure_type, ret_type) = match &signature {
|
||||||
|
Type::Function(arg_types, signature_closure_type, ret_type) => {
|
||||||
|
(arg_types, signature_closure_type, ret_type)
|
||||||
|
}
|
||||||
|
_ => todo!("TODO {:?}", (loc_symbol, &signature)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type::Function(arg_types, signature_closure_type, ret_type),
|
||||||
|
let ret_type = *ret_type.clone();
|
||||||
|
|
||||||
|
vars.push(ret_var);
|
||||||
|
vars.push(closure_var);
|
||||||
|
vars.push(closure_ext_var);
|
||||||
|
|
||||||
|
let mut def_pattern_state = PatternState::default();
|
||||||
|
|
||||||
|
def_pattern_state.headers.insert(
|
||||||
|
loc_symbol.value,
|
||||||
|
Loc {
|
||||||
|
region,
|
||||||
|
value: Type::Variable(expr_var),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
constrain_typed_function_arguments_simple(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_symbol.value,
|
||||||
|
&mut def_pattern_state,
|
||||||
|
&mut argument_pattern_state,
|
||||||
|
&function_def.arguments,
|
||||||
|
arg_types,
|
||||||
|
);
|
||||||
|
|
||||||
|
let closure_constraint = constrain_closure_size(
|
||||||
|
constraints,
|
||||||
|
loc_symbol.value,
|
||||||
|
region,
|
||||||
|
&function_def.captured_symbols,
|
||||||
|
closure_var,
|
||||||
|
closure_ext_var,
|
||||||
|
&mut vars,
|
||||||
|
);
|
||||||
|
|
||||||
|
let annotation_expected = FromAnnotation(
|
||||||
|
loc_pattern.clone(),
|
||||||
|
arity,
|
||||||
|
AnnotationSource::TypedBody {
|
||||||
|
region: annotation.region,
|
||||||
|
},
|
||||||
|
ret_type.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let ret_constraint = constrain_expr(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_body_expr.region,
|
||||||
|
&loc_body_expr.value,
|
||||||
|
annotation_expected,
|
||||||
|
);
|
||||||
|
|
||||||
|
vars.push(expr_var);
|
||||||
|
let defs_constraint = constraints.and_constraint(argument_pattern_state.constraints);
|
||||||
|
|
||||||
|
let signature_closure_type = *signature_closure_type.clone();
|
||||||
|
let signature_index = constraints.push_type(signature.clone());
|
||||||
|
let cons = [
|
||||||
|
constraints.let_constraint(
|
||||||
|
[],
|
||||||
|
argument_pattern_state.vars,
|
||||||
|
argument_pattern_state.headers,
|
||||||
|
defs_constraint,
|
||||||
|
ret_constraint,
|
||||||
|
),
|
||||||
|
constraints.equal_types_var(
|
||||||
|
closure_var,
|
||||||
|
Expected::FromAnnotation(
|
||||||
|
loc_pattern.clone(),
|
||||||
|
arity,
|
||||||
|
AnnotationSource::TypedBody {
|
||||||
|
region: annotation.region,
|
||||||
|
},
|
||||||
|
signature_closure_type,
|
||||||
|
),
|
||||||
|
Category::ClosureSize,
|
||||||
|
region,
|
||||||
|
),
|
||||||
|
constraints.store_index(signature_index, expr_var, std::file!(), std::line!()),
|
||||||
|
constraints.store_index(signature_index, expr_var, std::file!(), std::line!()),
|
||||||
|
constraints.store(ret_type, ret_var, std::file!(), std::line!()),
|
||||||
|
closure_constraint,
|
||||||
|
];
|
||||||
|
|
||||||
|
let expr_con = constraints.exists_many(vars, cons);
|
||||||
|
|
||||||
|
constrain_def_make_constraint_simple(
|
||||||
|
constraints,
|
||||||
|
new_rigid_variables,
|
||||||
|
new_infer_variables,
|
||||||
|
expr_con,
|
||||||
|
body_con,
|
||||||
|
loc_symbol,
|
||||||
|
expr_var,
|
||||||
|
signature,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
|
||||||
|
let expr_con = constrain_untyped_closure(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_function_def.region,
|
||||||
|
NoExpectation(expr_type),
|
||||||
|
expr_var,
|
||||||
|
function_def.closure_type,
|
||||||
|
function_def.closure_ext_var,
|
||||||
|
function_def.return_type,
|
||||||
|
&function_def.arguments,
|
||||||
|
loc_expr,
|
||||||
|
&function_def.captured_symbols,
|
||||||
|
loc_symbol.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
constrain_def_make_constraint_simple(
|
||||||
|
constraints,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
expr_con,
|
||||||
|
body_con,
|
||||||
|
loc_symbol,
|
||||||
|
expr_var,
|
||||||
|
Type::Variable(expr_var),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn constrain_value_def(
|
||||||
|
constraints: &mut Constraints,
|
||||||
|
env: &Env,
|
||||||
|
declarations: &Declarations,
|
||||||
|
index: usize,
|
||||||
|
body_con: Constraint,
|
||||||
|
) -> Constraint {
|
||||||
|
let loc_expr = &declarations.expressions[index];
|
||||||
|
let loc_symbol = declarations.symbols[index];
|
||||||
|
let expr_var = declarations.variables[index];
|
||||||
|
let opt_annotation = &declarations.annotations[index];
|
||||||
|
|
||||||
|
match opt_annotation {
|
||||||
|
Some(annotation) => {
|
||||||
|
let arity = 1;
|
||||||
|
let rigids = &env.rigids;
|
||||||
|
let mut ftv = rigids.clone();
|
||||||
|
|
||||||
|
let InstantiateRigids {
|
||||||
|
signature,
|
||||||
|
new_rigid_variables,
|
||||||
|
new_infer_variables,
|
||||||
|
} = instantiate_rigids_simple(
|
||||||
|
&annotation.signature,
|
||||||
|
&annotation.introduced_variables,
|
||||||
|
&mut ftv,
|
||||||
|
);
|
||||||
|
|
||||||
|
let loc_pattern = Loc::at(loc_symbol.region, Pattern::Identifier(loc_symbol.value));
|
||||||
|
|
||||||
|
let annotation_expected = FromAnnotation(
|
||||||
|
loc_pattern,
|
||||||
|
arity,
|
||||||
|
AnnotationSource::TypedBody {
|
||||||
|
region: annotation.region,
|
||||||
|
},
|
||||||
|
signature.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO missing equality of annotation_expected with expr_var?
|
||||||
|
// but the signature is stored into the expr_var below?!
|
||||||
|
|
||||||
|
let ret_constraint = constrain_expr(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_expr.region,
|
||||||
|
&loc_expr.value,
|
||||||
|
annotation_expected,
|
||||||
|
);
|
||||||
|
|
||||||
|
let cons = [
|
||||||
|
ret_constraint,
|
||||||
|
// Store type into AST vars. We use Store so errors aren't reported twice
|
||||||
|
constraints.store(signature.clone(), expr_var, std::file!(), std::line!()),
|
||||||
|
];
|
||||||
|
let expr_con = constraints.and_constraint(cons);
|
||||||
|
|
||||||
|
constrain_def_make_constraint_simple(
|
||||||
|
constraints,
|
||||||
|
new_rigid_variables,
|
||||||
|
new_infer_variables,
|
||||||
|
expr_con,
|
||||||
|
body_con,
|
||||||
|
loc_symbol,
|
||||||
|
expr_var,
|
||||||
|
signature,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
|
||||||
|
let expr_con = constrain_expr(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_expr.region,
|
||||||
|
&loc_expr.value,
|
||||||
|
NoExpectation(expr_type),
|
||||||
|
);
|
||||||
|
|
||||||
|
constrain_def_make_constraint_simple(
|
||||||
|
constraints,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
expr_con,
|
||||||
|
body_con,
|
||||||
|
loc_symbol,
|
||||||
|
expr_var,
|
||||||
|
Type::Variable(expr_var),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Constrain a when branch, returning (variables in pattern, symbols introduced in pattern, pattern constraint, body constraint).
|
/// Constrain a when branch, returning (variables in pattern, symbols introduced in pattern, pattern constraint, body constraint).
|
||||||
/// We want to constraint all pattern constraints in a "when" before body constraints.
|
/// We want to constraint all pattern constraints in a "when" before body constraints.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -1609,7 +1807,7 @@ fn constrain_empty_record(
|
||||||
pub fn constrain_decls(
|
pub fn constrain_decls(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
decls: &[Declaration],
|
declarations: &Declarations,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let mut constraint = Constraint::SaveTheEnvironment;
|
let mut constraint = Constraint::SaveTheEnvironment;
|
||||||
|
|
||||||
|
@ -1618,22 +1816,42 @@ pub fn constrain_decls(
|
||||||
rigids: MutMap::default(),
|
rigids: MutMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for decl in decls.iter().rev() {
|
debug_assert_eq!(declarations.declarations.len(), declarations.symbols.len());
|
||||||
|
|
||||||
|
for (index, tag) in declarations.iter_top_down() {
|
||||||
// Clear the rigids from the previous iteration.
|
// Clear the rigids from the previous iteration.
|
||||||
// rigids are not shared between top-level definitions
|
// rigids are not shared between top-level definitions
|
||||||
env.rigids.clear();
|
env.rigids.clear();
|
||||||
|
|
||||||
match decl {
|
use roc_can::expr::DeclarationTag::*;
|
||||||
Declaration::Declare(def) | Declaration::Builtin(def) => {
|
match tag {
|
||||||
constraint = constrain_def(constraints, &env, def, constraint);
|
Value => {
|
||||||
|
constraint =
|
||||||
|
constrain_value_def(constraints, &env, declarations, index, constraint);
|
||||||
}
|
}
|
||||||
Declaration::DeclareRec(defs) => {
|
Function(function_def_index) => {
|
||||||
constraint = constrain_recursive_defs(constraints, &env, defs, constraint);
|
constraint = constrain_function_def(
|
||||||
|
constraints,
|
||||||
|
&env,
|
||||||
|
declarations,
|
||||||
|
index,
|
||||||
|
function_def_index,
|
||||||
|
constraint,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Declaration::InvalidCycle(_) => {
|
Recursive(function_def_index) | TailRecursive(function_def_index) => {
|
||||||
// invalid cycles give a canonicalization error. we skip them here.
|
// for the type it does not matter that a recursive call is a tail call
|
||||||
continue;
|
constraint = constrain_recursive_defs_simple(
|
||||||
|
constraints,
|
||||||
|
&env,
|
||||||
|
declarations,
|
||||||
|
index,
|
||||||
|
function_def_index.as_slice(),
|
||||||
|
constraint,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
Destructure(_) => todo!(),
|
||||||
|
MutualRecursion(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2381,6 +2599,255 @@ fn instantiate_rigids_simple(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constrain_recursive_defs_simple(
|
||||||
|
constraints: &mut Constraints,
|
||||||
|
env: &Env,
|
||||||
|
declarations: &Declarations,
|
||||||
|
start_index: usize,
|
||||||
|
defs: Slice<Loc<FunctionDef>>,
|
||||||
|
body_con: Constraint,
|
||||||
|
) -> Constraint {
|
||||||
|
rec_defs_help_simple(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
declarations,
|
||||||
|
defs,
|
||||||
|
start_index,
|
||||||
|
body_con,
|
||||||
|
Info::with_capacity(defs.len()),
|
||||||
|
Info::with_capacity(defs.len()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rec_defs_help_simple(
|
||||||
|
constraints: &mut Constraints,
|
||||||
|
env: &Env,
|
||||||
|
declarations: &Declarations,
|
||||||
|
defs: Slice<Loc<FunctionDef>>,
|
||||||
|
start_index: usize,
|
||||||
|
body_con: Constraint,
|
||||||
|
mut rigid_info: Info,
|
||||||
|
mut flex_info: Info,
|
||||||
|
) -> Constraint {
|
||||||
|
for (index, function_def_index) in (start_index..).zip(defs.indices()) {
|
||||||
|
let loc_expr = &declarations.expressions[index];
|
||||||
|
let loc_symbol = declarations.symbols[index];
|
||||||
|
let expr_var = declarations.variables[index];
|
||||||
|
let opt_annotation = &declarations.annotations[index];
|
||||||
|
|
||||||
|
let loc_function_def = &declarations.function_bodies[function_def_index];
|
||||||
|
let function_def = &loc_function_def.value;
|
||||||
|
|
||||||
|
match opt_annotation {
|
||||||
|
None => {
|
||||||
|
let expr_type = Type::Variable(expr_var);
|
||||||
|
|
||||||
|
let expr_con = constrain_untyped_closure(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_function_def.region,
|
||||||
|
NoExpectation(expr_type),
|
||||||
|
expr_var,
|
||||||
|
function_def.closure_type,
|
||||||
|
function_def.closure_ext_var,
|
||||||
|
function_def.return_type,
|
||||||
|
&function_def.arguments,
|
||||||
|
loc_expr,
|
||||||
|
&function_def.captured_symbols,
|
||||||
|
loc_symbol.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
let def_con = expr_con;
|
||||||
|
|
||||||
|
flex_info.vars = vec![expr_var];
|
||||||
|
flex_info.constraints.push(def_con);
|
||||||
|
flex_info.def_types.insert(
|
||||||
|
loc_symbol.value,
|
||||||
|
Loc::at(loc_symbol.region, Type::Variable(expr_var)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(annotation) => {
|
||||||
|
let arity = annotation.signature.arity();
|
||||||
|
let rigids = &env.rigids;
|
||||||
|
let mut ftv = rigids.clone();
|
||||||
|
|
||||||
|
let InstantiateRigids {
|
||||||
|
signature,
|
||||||
|
new_rigid_variables,
|
||||||
|
new_infer_variables,
|
||||||
|
} = instantiate_rigids_simple(
|
||||||
|
&annotation.signature,
|
||||||
|
&annotation.introduced_variables,
|
||||||
|
&mut ftv,
|
||||||
|
);
|
||||||
|
|
||||||
|
let loc_pattern = Loc::at(loc_symbol.region, Pattern::Identifier(loc_symbol.value));
|
||||||
|
|
||||||
|
flex_info.vars.extend(new_infer_variables);
|
||||||
|
|
||||||
|
let annotation_expected = FromAnnotation(
|
||||||
|
loc_pattern.clone(),
|
||||||
|
arity,
|
||||||
|
AnnotationSource::TypedBody {
|
||||||
|
region: annotation.region,
|
||||||
|
},
|
||||||
|
signature.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let (arg_types, _signature_closure_type, ret_type) = match &signature {
|
||||||
|
Type::Function(arg_types, signature_closure_type, ret_type) => {
|
||||||
|
(arg_types, signature_closure_type, ret_type)
|
||||||
|
}
|
||||||
|
_ => todo!("TODO {:?}", (loc_symbol, &signature)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected = annotation_expected;
|
||||||
|
let region = loc_function_def.region;
|
||||||
|
|
||||||
|
let loc_body_expr = loc_expr;
|
||||||
|
let mut argument_pattern_state = PatternState {
|
||||||
|
headers: SendMap::default(),
|
||||||
|
vars: Vec::with_capacity(function_def.arguments.len()),
|
||||||
|
constraints: Vec::with_capacity(1),
|
||||||
|
delayed_is_open_constraints: vec![],
|
||||||
|
};
|
||||||
|
let mut vars = Vec::with_capacity(argument_pattern_state.vars.capacity() + 1);
|
||||||
|
let ret_var = function_def.return_type;
|
||||||
|
let closure_var = function_def.closure_type;
|
||||||
|
let closure_ext_var = function_def.closure_ext_var;
|
||||||
|
let ret_type = *ret_type.clone();
|
||||||
|
|
||||||
|
vars.push(ret_var);
|
||||||
|
vars.push(closure_var);
|
||||||
|
vars.push(closure_ext_var);
|
||||||
|
|
||||||
|
let mut def_pattern_state = PatternState::default();
|
||||||
|
|
||||||
|
def_pattern_state.headers.insert(
|
||||||
|
loc_symbol.value,
|
||||||
|
Loc {
|
||||||
|
region,
|
||||||
|
value: Type::Variable(expr_var),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
constrain_typed_function_arguments_simple(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_symbol.value,
|
||||||
|
&mut def_pattern_state,
|
||||||
|
&mut argument_pattern_state,
|
||||||
|
&function_def.arguments,
|
||||||
|
arg_types,
|
||||||
|
);
|
||||||
|
|
||||||
|
let pattern_types = function_def
|
||||||
|
.arguments
|
||||||
|
.iter()
|
||||||
|
.map(|a| Type::Variable(a.0))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let closure_constraint = constrain_closure_size(
|
||||||
|
constraints,
|
||||||
|
loc_symbol.value,
|
||||||
|
region,
|
||||||
|
&function_def.captured_symbols,
|
||||||
|
closure_var,
|
||||||
|
closure_ext_var,
|
||||||
|
&mut vars,
|
||||||
|
);
|
||||||
|
|
||||||
|
let fn_type = Type::Function(
|
||||||
|
pattern_types,
|
||||||
|
Box::new(Type::Variable(closure_var)),
|
||||||
|
Box::new(ret_type.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let expr_con = constrain_expr(
|
||||||
|
constraints,
|
||||||
|
env,
|
||||||
|
loc_body_expr.region,
|
||||||
|
&loc_body_expr.value,
|
||||||
|
NoExpectation(ret_type.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
vars.push(expr_var);
|
||||||
|
|
||||||
|
let signature_index = constraints.push_type(signature);
|
||||||
|
let state_constraints =
|
||||||
|
constraints.and_constraint(argument_pattern_state.constraints);
|
||||||
|
let cons = [
|
||||||
|
constraints.let_constraint(
|
||||||
|
[],
|
||||||
|
argument_pattern_state.vars,
|
||||||
|
argument_pattern_state.headers,
|
||||||
|
state_constraints,
|
||||||
|
expr_con,
|
||||||
|
),
|
||||||
|
constraints.equal_types(
|
||||||
|
fn_type.clone(),
|
||||||
|
expected.clone(),
|
||||||
|
Category::Lambda,
|
||||||
|
region,
|
||||||
|
),
|
||||||
|
// "fn_var is equal to the closure's type" - fn_var is used in code gen
|
||||||
|
// Store type into AST vars. We use Store so errors aren't reported twice
|
||||||
|
constraints.store_index(signature_index, expr_var, std::file!(), std::line!()),
|
||||||
|
constraints.store(ret_type, ret_var, std::file!(), std::line!()),
|
||||||
|
closure_constraint,
|
||||||
|
];
|
||||||
|
|
||||||
|
let and_constraint = constraints.and_constraint(cons);
|
||||||
|
let def_con = constraints.exists(vars, and_constraint);
|
||||||
|
|
||||||
|
rigid_info.vars.extend(&new_rigid_variables);
|
||||||
|
|
||||||
|
rigid_info.constraints.push(constraints.let_constraint(
|
||||||
|
new_rigid_variables,
|
||||||
|
def_pattern_state.vars,
|
||||||
|
[], // no headers introduced (at this level)
|
||||||
|
def_con,
|
||||||
|
Constraint::True,
|
||||||
|
));
|
||||||
|
rigid_info.def_types.extend(def_pattern_state.headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let flex_constraints = constraints.and_constraint(flex_info.constraints);
|
||||||
|
let inner_inner = constraints.let_constraint(
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
flex_info.def_types.clone(),
|
||||||
|
Constraint::True,
|
||||||
|
flex_constraints,
|
||||||
|
);
|
||||||
|
|
||||||
|
let rigid_constraints = {
|
||||||
|
let mut temp = rigid_info.constraints;
|
||||||
|
temp.push(body_con);
|
||||||
|
|
||||||
|
constraints.and_constraint(temp)
|
||||||
|
};
|
||||||
|
|
||||||
|
let inner = constraints.let_constraint(
|
||||||
|
[],
|
||||||
|
flex_info.vars,
|
||||||
|
flex_info.def_types,
|
||||||
|
inner_inner,
|
||||||
|
rigid_constraints,
|
||||||
|
);
|
||||||
|
|
||||||
|
constraints.let_constraint(
|
||||||
|
rigid_info.vars,
|
||||||
|
[],
|
||||||
|
rigid_info.def_types,
|
||||||
|
Constraint::True,
|
||||||
|
inner,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn constrain_recursive_defs(
|
fn constrain_recursive_defs(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
env: &Env,
|
env: &Env,
|
||||||
|
|
|
@ -4,6 +4,7 @@ use roc_can::abilities::AbilitiesStore;
|
||||||
use roc_can::constraint::{Constraint, Constraints};
|
use roc_can::constraint::{Constraint, Constraints};
|
||||||
use roc_can::def::Declaration;
|
use roc_can::def::Declaration;
|
||||||
use roc_can::expected::Expected;
|
use roc_can::expected::Expected;
|
||||||
|
use roc_can::expr::Declarations;
|
||||||
use roc_can::pattern::Pattern;
|
use roc_can::pattern::Pattern;
|
||||||
use roc_collections::all::MutMap;
|
use roc_collections::all::MutMap;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
|
@ -98,7 +99,7 @@ pub fn constrain_module(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
symbols_from_requires: Vec<(Loc<Symbol>, Loc<Type>)>,
|
symbols_from_requires: Vec<(Loc<Symbol>, Loc<Type>)>,
|
||||||
abilities_store: &AbilitiesStore,
|
abilities_store: &AbilitiesStore,
|
||||||
declarations: &[Declaration],
|
declarations: &Declarations,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let constraint = crate::expr::constrain_decls(constraints, home, declarations);
|
let constraint = crate::expr::constrain_decls(constraints, home, declarations);
|
||||||
|
|
|
@ -9,6 +9,7 @@ use roc_builtins::std::borrow_stdlib;
|
||||||
use roc_can::abilities::AbilitiesStore;
|
use roc_can::abilities::AbilitiesStore;
|
||||||
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints};
|
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints};
|
||||||
use roc_can::def::Declaration;
|
use roc_can::def::Declaration;
|
||||||
|
use roc_can::expr::Declarations;
|
||||||
use roc_can::module::{canonicalize_module_defs, Module};
|
use roc_can::module::{canonicalize_module_defs, Module};
|
||||||
use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecSet};
|
use roc_collections::{default_hasher, BumpMap, MutMap, MutSet, VecSet};
|
||||||
use roc_constrain::module::{
|
use roc_constrain::module::{
|
||||||
|
@ -459,7 +460,7 @@ pub struct LoadedModule {
|
||||||
pub solved: Solved<Subs>,
|
pub solved: Solved<Subs>,
|
||||||
pub can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
|
pub can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
|
||||||
pub type_problems: MutMap<ModuleId, Vec<solve::TypeError>>,
|
pub type_problems: MutMap<ModuleId, Vec<solve::TypeError>>,
|
||||||
pub declarations_by_id: MutMap<ModuleId, Vec<Declaration>>,
|
pub declarations_by_id: MutMap<ModuleId, Declarations>,
|
||||||
pub exposed_to_host: MutMap<Symbol, Variable>,
|
pub exposed_to_host: MutMap<Symbol, Variable>,
|
||||||
pub dep_idents: IdentIdsByModule,
|
pub dep_idents: IdentIdsByModule,
|
||||||
pub exposed_aliases: MutMap<Symbol, Alias>,
|
pub exposed_aliases: MutMap<Symbol, Alias>,
|
||||||
|
@ -520,7 +521,7 @@ struct ModuleHeader<'a> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ConstrainedModule {
|
struct ConstrainedModule {
|
||||||
module: Module,
|
module: Module,
|
||||||
declarations: Vec<Declaration>,
|
declarations: Declarations,
|
||||||
imported_modules: MutMap<ModuleId, Region>,
|
imported_modules: MutMap<ModuleId, Region>,
|
||||||
constraints: Constraints,
|
constraints: Constraints,
|
||||||
constraint: ConstraintSoa,
|
constraint: ConstraintSoa,
|
||||||
|
@ -536,7 +537,7 @@ pub struct TypeCheckedModule<'a> {
|
||||||
pub layout_cache: LayoutCache<'a>,
|
pub layout_cache: LayoutCache<'a>,
|
||||||
pub module_timing: ModuleTiming,
|
pub module_timing: ModuleTiming,
|
||||||
pub solved_subs: Solved<Subs>,
|
pub solved_subs: Solved<Subs>,
|
||||||
pub decls: Vec<Declaration>,
|
pub decls: Declarations,
|
||||||
pub ident_ids: IdentIds,
|
pub ident_ids: IdentIds,
|
||||||
pub abilities_store: AbilitiesStore,
|
pub abilities_store: AbilitiesStore,
|
||||||
}
|
}
|
||||||
|
@ -621,7 +622,7 @@ enum Msg<'a> {
|
||||||
ident_ids: IdentIds,
|
ident_ids: IdentIds,
|
||||||
solved_module: SolvedModule,
|
solved_module: SolvedModule,
|
||||||
solved_subs: Solved<Subs>,
|
solved_subs: Solved<Subs>,
|
||||||
decls: Vec<Declaration>,
|
decls: Declarations,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
abilities_store: AbilitiesStore,
|
abilities_store: AbilitiesStore,
|
||||||
|
@ -718,7 +719,7 @@ struct State<'a> {
|
||||||
|
|
||||||
pub ident_ids_by_module: SharedIdentIdsByModule,
|
pub ident_ids_by_module: SharedIdentIdsByModule,
|
||||||
|
|
||||||
pub declarations_by_id: MutMap<ModuleId, Vec<Declaration>>,
|
pub declarations_by_id: MutMap<ModuleId, Declarations>,
|
||||||
|
|
||||||
pub exposed_symbols_by_module: MutMap<ModuleId, VecSet<Symbol>>,
|
pub exposed_symbols_by_module: MutMap<ModuleId, VecSet<Symbol>>,
|
||||||
|
|
||||||
|
@ -879,7 +880,7 @@ enum BuildTask<'a> {
|
||||||
constraints: Constraints,
|
constraints: Constraints,
|
||||||
constraint: ConstraintSoa,
|
constraint: ConstraintSoa,
|
||||||
var_store: VarStore,
|
var_store: VarStore,
|
||||||
declarations: Vec<Declaration>,
|
declarations: Declarations,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
},
|
},
|
||||||
|
@ -890,7 +891,7 @@ enum BuildTask<'a> {
|
||||||
imported_module_thunks: &'a [Symbol],
|
imported_module_thunks: &'a [Symbol],
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
ident_ids: IdentIds,
|
ident_ids: IdentIds,
|
||||||
decls: Vec<Declaration>,
|
decls: Declarations,
|
||||||
exposed_to_host: ExposedToHost,
|
exposed_to_host: ExposedToHost,
|
||||||
abilities_store: AbilitiesStore,
|
abilities_store: AbilitiesStore,
|
||||||
},
|
},
|
||||||
|
@ -3544,7 +3545,7 @@ impl<'a> BuildTask<'a> {
|
||||||
imported_modules: MutMap<ModuleId, Region>,
|
imported_modules: MutMap<ModuleId, Region>,
|
||||||
exposed_types: &mut ExposedByModule,
|
exposed_types: &mut ExposedByModule,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
declarations: Vec<Declaration>,
|
declarations: Declarations,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let exposed_by_module = exposed_types.retain_modules(imported_modules.keys());
|
let exposed_by_module = exposed_types.retain_modules(imported_modules.keys());
|
||||||
|
@ -3724,7 +3725,7 @@ fn run_solve<'a>(
|
||||||
constraints: Constraints,
|
constraints: Constraints,
|
||||||
constraint: ConstraintSoa,
|
constraint: ConstraintSoa,
|
||||||
var_store: VarStore,
|
var_store: VarStore,
|
||||||
decls: Vec<Declaration>,
|
decls: Declarations,
|
||||||
dep_idents: IdentIdsByModule,
|
dep_idents: IdentIdsByModule,
|
||||||
cached_subs: CachedSubs,
|
cached_subs: CachedSubs,
|
||||||
) -> Msg<'a> {
|
) -> Msg<'a> {
|
||||||
|
@ -4188,7 +4189,7 @@ fn build_pending_specializations<'a>(
|
||||||
imported_module_thunks: &'a [Symbol],
|
imported_module_thunks: &'a [Symbol],
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
mut ident_ids: IdentIds,
|
mut ident_ids: IdentIds,
|
||||||
decls: Vec<Declaration>,
|
decls: Declarations,
|
||||||
mut module_timing: ModuleTiming,
|
mut module_timing: ModuleTiming,
|
||||||
mut layout_cache: LayoutCache<'a>,
|
mut layout_cache: LayoutCache<'a>,
|
||||||
target_info: TargetInfo,
|
target_info: TargetInfo,
|
||||||
|
@ -4224,6 +4225,8 @@ fn build_pending_specializations<'a>(
|
||||||
abilities_store: &mut abilities_store,
|
abilities_store: &mut abilities_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let decls = [];
|
||||||
|
|
||||||
// Add modules' decls to Procs
|
// Add modules' decls to Procs
|
||||||
for decl in decls {
|
for decl in decls {
|
||||||
use roc_can::def::Declaration::*;
|
use roc_can::def::Declaration::*;
|
||||||
|
|
|
@ -3,4 +3,7 @@ app "helloZig"
|
||||||
imports []
|
imports []
|
||||||
provides [ main ] to pf
|
provides [ main ] to pf
|
||||||
|
|
||||||
main = "Hello, World!\n"
|
f : Str -> Str
|
||||||
|
f = \s -> Str.concat s "!"
|
||||||
|
|
||||||
|
main = f "Hello, World!\n"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue