mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Correctly generate type constraints for required symbols in platform
This commit is contained in:
parent
e8fbda44fc
commit
c7142da116
7 changed files with 35 additions and 17 deletions
|
@ -1300,7 +1300,7 @@ pub fn constrain_decls(
|
||||||
constraint
|
constraint
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constrain_def_pattern(
|
pub fn constrain_def_pattern(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
env: &Env,
|
env: &Env,
|
||||||
loc_pattern: &Loc<Pattern>,
|
loc_pattern: &Loc<Pattern>,
|
||||||
|
@ -1706,7 +1706,7 @@ fn constrain_def(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constrain_def_make_constraint(
|
pub fn constrain_def_make_constraint(
|
||||||
constraints: &mut Constraints,
|
constraints: &mut Constraints,
|
||||||
new_rigid_variables: Vec<Variable>,
|
new_rigid_variables: Vec<Variable>,
|
||||||
new_infer_variables: Vec<Variable>,
|
new_infer_variables: Vec<Variable>,
|
||||||
|
|
|
@ -11,6 +11,8 @@ use roc_types::solved_types::{FreeVars, SolvedType};
|
||||||
use roc_types::subs::{VarStore, Variable};
|
use roc_types::subs::{VarStore, Variable};
|
||||||
use roc_types::types::{Category, Type};
|
use roc_types::types::{Category, Type};
|
||||||
|
|
||||||
|
use crate::expr::{constrain_def_make_constraint, constrain_def_pattern, Env};
|
||||||
|
|
||||||
/// The types of all exposed values/functions of a collection of modules
|
/// The types of all exposed values/functions of a collection of modules
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct ExposedByModule {
|
pub struct ExposedByModule {
|
||||||
|
@ -116,28 +118,43 @@ fn constrain_symbols_from_requires(
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
constraint: Constraint,
|
constraint: Constraint,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
// TODO thread through rigid_vars and flex_vars
|
|
||||||
let rigid_vars = std::iter::empty();
|
|
||||||
let flex_vars = std::iter::empty();
|
|
||||||
|
|
||||||
symbols_from_requires
|
symbols_from_requires
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold(constraint, |constraint, (symbol, loc_type)| {
|
.fold(constraint, |constraint, (symbol, loc_type)| {
|
||||||
if symbol.module_id() == home {
|
if symbol.module_id() == home {
|
||||||
constraints.let_constraint(
|
// 1. Required symbols can only be specified in package modules
|
||||||
rigid_vars.clone(),
|
// 2. Required symbols come from app modules
|
||||||
flex_vars.clone(),
|
// But, if we are running e.g. `roc check` on a package module, there is no app
|
||||||
std::iter::once((symbol, loc_type)),
|
// module, and we will have instead put the required symbols in the package module
|
||||||
|
// namespace. If this is the case, we want to introduce the symbols as if they had
|
||||||
|
// the types they are annotated with.
|
||||||
|
let rigids = Default::default();
|
||||||
|
let env = Env { home, rigids };
|
||||||
|
let pattern = Loc::at_zero(roc_can::pattern::Pattern::Identifier(symbol));
|
||||||
|
|
||||||
|
let def_pattern_state =
|
||||||
|
constrain_def_pattern(constraints, &env, &pattern, loc_type.value.clone());
|
||||||
|
|
||||||
|
constrain_def_make_constraint(
|
||||||
|
constraints,
|
||||||
|
// No new rigids or flex vars because they are represented in the type
|
||||||
|
// annotation.
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
Constraint::True,
|
Constraint::True,
|
||||||
constraint,
|
constraint,
|
||||||
|
def_pattern_state,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
constraints.lookup(
|
// Otherwise, this symbol comes from an app module - we want to check that the type
|
||||||
|
// provided by the app is in fact what the package module requires.
|
||||||
|
let provided_eq_requires_constr = constraints.lookup(
|
||||||
symbol,
|
symbol,
|
||||||
// TODO give it a real expectation, so errors can be helpful
|
// TODO give it a real expectation, so errors can be helpful
|
||||||
Expected::NoExpectation(loc_type.value),
|
Expected::NoExpectation(loc_type.value),
|
||||||
loc_type.region,
|
loc_type.region,
|
||||||
)
|
);
|
||||||
|
constraints.and_constraint([provided_eq_requires_constr, constraint])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ app "deriv"
|
||||||
# based on: https://github.com/koka-lang/koka/blob/master/test/bench/haskell/deriv.hs
|
# based on: https://github.com/koka-lang/koka/blob/master/test/bench/haskell/deriv.hs
|
||||||
IO a : Task.Task a []
|
IO a : Task.Task a []
|
||||||
|
|
||||||
main : IO {}
|
main : Task.Task {} []
|
||||||
main =
|
main =
|
||||||
Task.after
|
Task.after
|
||||||
Task.getInt
|
Task.getInt
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
platform "benchmarks"
|
platform "benchmarks"
|
||||||
requires {} { main : Effect {} }
|
requires {} { main : Task {} [] }
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports [ Task.{ Task } ]
|
imports [ Task.{ Task } ]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
platform "effects"
|
platform "effects"
|
||||||
requires {} { main : Effect {} }
|
requires {} { main : Effect.Effect {} }
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports [ pf.Effect ]
|
imports [ pf.Effect ]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
platform "tui"
|
platform "tui"
|
||||||
requires { Model } { main : Effect {} }
|
requires { Model } { main : { init : ({} -> Model), update : (Model, Str -> Model), view : (Model -> Str) } }
|
||||||
exposes []
|
exposes []
|
||||||
packages {}
|
packages {}
|
||||||
imports []
|
imports []
|
||||||
|
|
|
@ -385,7 +385,8 @@ impl<'a> RocDocAllocator<'a> {
|
||||||
pub fn tag_name(&'a self, tn: TagName) -> DocBuilder<'a, Self, Annotation> {
|
pub fn tag_name(&'a self, tn: TagName) -> DocBuilder<'a, Self, Annotation> {
|
||||||
match tn {
|
match tn {
|
||||||
TagName::Tag(uppercase) => self.tag(uppercase),
|
TagName::Tag(uppercase) => self.tag(uppercase),
|
||||||
TagName::Closure(_symbol) => unreachable!("closure tags are internal only"),
|
TagName::Closure(symbol) => self.symbol_qualified(symbol),
|
||||||
|
// TagName::Closure(_symbol) => unreachable!("closure tags are internal only"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue