mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge pull request #787 from rtfeldman/record-unresolved-typevar
Trim used variables
This commit is contained in:
commit
4ba96b4a3a
5 changed files with 154 additions and 17 deletions
|
@ -26,6 +26,95 @@ macro_rules! defs {
|
|||
};
|
||||
}
|
||||
|
||||
macro_rules! macro_magic {
|
||||
(@single $($x:tt)*) => (());
|
||||
(@count $($rest:expr),*) => (<[()]>::len(&[$(matches!(@single $rest)),*]));
|
||||
|
||||
($symbol:expr; $var_store:expr; $($key:ident => $func:expr,)+) => { macro_magic!($symbol; $var_store; $($key => $func),+) };
|
||||
($symbol:expr; $var_store:expr; $($key:ident => $func:expr),*) => {
|
||||
{
|
||||
match $symbol {
|
||||
$(
|
||||
Symbol::$key => Some($func(Symbol::$key, $var_store)),
|
||||
)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def> {
|
||||
debug_assert!(symbol.is_builtin());
|
||||
|
||||
macro_magic! { symbol; var_store;
|
||||
BOOL_EQ => bool_eq,
|
||||
BOOL_NEQ => bool_neq,
|
||||
BOOL_AND => bool_and,
|
||||
BOOL_OR => bool_or,
|
||||
BOOL_NOT => bool_not,
|
||||
STR_CONCAT => str_concat,
|
||||
STR_SPLIT => str_split,
|
||||
STR_IS_EMPTY => str_is_empty,
|
||||
STR_STARTS_WITH => str_starts_with,
|
||||
STR_ENDS_WITH => str_ends_with,
|
||||
STR_COUNT_GRAPHEMES => str_count_graphemes,
|
||||
STR_FROM_INT => str_from_int,
|
||||
LIST_LEN => list_len,
|
||||
LIST_GET => list_get,
|
||||
LIST_SET => list_set,
|
||||
LIST_APPEND => list_append,
|
||||
LIST_FIRST => list_first,
|
||||
LIST_IS_EMPTY => list_is_empty,
|
||||
LIST_SINGLE => list_single,
|
||||
LIST_REPEAT => list_repeat,
|
||||
LIST_REVERSE => list_reverse,
|
||||
LIST_CONCAT => list_concat,
|
||||
LIST_CONTAINS => list_contains,
|
||||
LIST_SUM => list_sum,
|
||||
LIST_PREPEND => list_prepend,
|
||||
LIST_JOIN => list_join,
|
||||
LIST_MAP => list_map,
|
||||
LIST_KEEP_IF => list_keep_if,
|
||||
LIST_WALK => list_walk,
|
||||
LIST_WALK_BACKWARDS => list_walk_backwards,
|
||||
NUM_ADD => num_add,
|
||||
NUM_ADD_CHECKED => num_add_checked,
|
||||
NUM_ADD_WRAP => num_add_wrap,
|
||||
NUM_SUB => num_sub,
|
||||
NUM_MUL => num_mul,
|
||||
NUM_GT => num_gt,
|
||||
NUM_GTE => num_gte,
|
||||
NUM_LT => num_lt,
|
||||
NUM_LTE => num_lte,
|
||||
NUM_COMPARE => num_compare,
|
||||
NUM_SIN => num_sin,
|
||||
NUM_COS => num_cos,
|
||||
NUM_TAN => num_tan,
|
||||
NUM_DIV_FLOAT => num_div_float,
|
||||
NUM_DIV_INT => num_div_int,
|
||||
NUM_ABS => num_abs,
|
||||
NUM_NEG => num_neg,
|
||||
NUM_REM => num_rem,
|
||||
NUM_SQRT => num_sqrt,
|
||||
NUM_ROUND => num_round,
|
||||
NUM_IS_ODD => num_is_odd,
|
||||
NUM_IS_EVEN => num_is_even,
|
||||
NUM_IS_ZERO => num_is_zero,
|
||||
NUM_IS_POSITIVE => num_is_positive,
|
||||
NUM_IS_NEGATIVE => num_is_negative,
|
||||
NUM_TO_FLOAT => num_to_float,
|
||||
NUM_POW => num_pow,
|
||||
NUM_CEILING => num_ceiling,
|
||||
NUM_POW_INT => num_pow_int,
|
||||
NUM_FLOOR => num_floor,
|
||||
NUM_ATAN => num_atan,
|
||||
NUM_ACOS => num_acos,
|
||||
NUM_ASIN => num_asin,
|
||||
NUM_MAX_INT => num_max_int,
|
||||
NUM_MIN_INT => num_min_int,
|
||||
}
|
||||
}
|
||||
|
||||
/// Some builtins cannot be constructed in code gen alone, and need to be defined
|
||||
/// as separate Roc defs. For example, List.get has this type:
|
||||
///
|
||||
|
|
|
@ -269,12 +269,14 @@ pub fn canonicalize_module_defs<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
// Add builtin defs (e.g. List.get) to the module's defs
|
||||
let builtin_defs = builtins::builtin_defs(var_store);
|
||||
|
||||
for (symbol, def) in builtin_defs {
|
||||
if references.contains(&symbol) {
|
||||
declarations.push(Declaration::Builtin(def));
|
||||
// TODO this loops over all symbols in the module, we can speed it up by having an
|
||||
// iterator over all builtin symbols
|
||||
for symbol in references.iter() {
|
||||
if symbol.is_builtin() {
|
||||
// this can fail when the symbol is for builtin types, or has no implementation yet
|
||||
if let Some(def) = builtins::builtin_defs_map(*symbol, var_store) {
|
||||
declarations.push(Declaration::Builtin(def));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -868,4 +868,56 @@ mod gen_tags {
|
|||
(i64, bool, u8)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn phantom_polymorphic() {
|
||||
// see https://github.com/rtfeldman/roc/issues/786 and below
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r"#
|
||||
Point coordinate : [ Point coordinate I64 I64 ]
|
||||
|
||||
World : [ @World ]
|
||||
|
||||
zero : Point World
|
||||
zero = Point @World 0 0
|
||||
|
||||
add : Point a -> Point a
|
||||
add = \(Point c x y) -> (Point c x y)
|
||||
|
||||
add zero
|
||||
#"
|
||||
),
|
||||
(0, 0),
|
||||
(i64, i64)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn phantom_polymorphic_record() {
|
||||
// see https://github.com/rtfeldman/roc/issues/786
|
||||
// also seemed to hit an issue where we check whether `add`
|
||||
// has a Closure layout while the type is not fully specialized yet
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [ main ] to "./platform"
|
||||
|
||||
Point coordinate : { coordinate : coordinate, x : I64, y : I64 }
|
||||
|
||||
zero : Point I64
|
||||
zero = { coordinate : 0, x : 0, y : 0 }
|
||||
|
||||
add : Point a -> Point a
|
||||
add = \{ coordinate } -> { coordinate, x: 0 + 0, y: 0 }
|
||||
|
||||
main = add zero
|
||||
"#
|
||||
),
|
||||
(0, 0),
|
||||
(i64, i64)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3183,17 +3183,7 @@ fn canonicalize_and_constrain<'a>(
|
|||
module_timing.canonicalize = canonicalize_end.duration_since(canonicalize_start).unwrap();
|
||||
|
||||
match canonicalized {
|
||||
Ok(mut module_output) => {
|
||||
// Add builtin defs (e.g. List.get) to the module's defs
|
||||
let builtin_defs = roc_can::builtins::builtin_defs(&mut var_store);
|
||||
let references = &module_output.references;
|
||||
|
||||
for (symbol, def) in builtin_defs {
|
||||
if references.contains(&symbol) {
|
||||
module_output.declarations.push(Declaration::Builtin(def));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(module_output) => {
|
||||
let constraint = constrain_module(&module_output, module_id, mode, &mut var_store);
|
||||
|
||||
let module = Module {
|
||||
|
|
|
@ -1245,6 +1245,10 @@ fn patterns_to_when<'a>(
|
|||
// patterns that are not yet in a when (e.g. in let or function arguments) must be irrefutable
|
||||
// to pass type checking. So the order in which we add them to the body does not matter: there
|
||||
// are only stores anyway, no branches.
|
||||
//
|
||||
// NOTE this fails if the pattern contains rigid variables,
|
||||
// see https://github.com/rtfeldman/roc/issues/786
|
||||
// this must be fixed when moving exhaustiveness checking to the new canonical AST
|
||||
for (pattern_var, pattern) in patterns.into_iter() {
|
||||
let context = crate::exhaustive::Context::BadArg;
|
||||
let mono_pattern = from_can_pattern(env, layout_cache, &pattern.value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue