diff --git a/src/solve.rs b/src/solve.rs index 0af38bb04c..288979ad6c 100644 --- a/src/solve.rs +++ b/src/solve.rs @@ -7,7 +7,6 @@ use crate::types::Constraint::{self, *}; use crate::types::Problem; use crate::types::Type::{self, *}; use crate::unify::{unify, Unified}; -use crate::uniqueness::boolean_algebra::Bool; type Env = ImMap; @@ -402,7 +401,6 @@ fn type_to_variable( register(subs, rank, pools, content) } - // Boolean(Bool::Variable(var)) => *var, Boolean(b) => { let content = Content::Structure(FlatType::Boolean(b.clone())); diff --git a/src/uniqueness/mod.rs b/src/uniqueness/mod.rs index 9114130604..7ff892483a 100644 --- a/src/uniqueness/mod.rs +++ b/src/uniqueness/mod.rs @@ -119,27 +119,23 @@ fn constrain_pattern( } in patterns { let pat_type = Type::Variable(*var); - let pattern_expected = PExpected::NoExpectation(pat_type.clone()); + let expected = PExpected::NoExpectation(pat_type.clone()); - match guard { - Some((_guard_var, loc_guard)) => { - state.headers.insert( - symbol.clone(), - Located { - region: pattern.region, - value: pat_type.clone(), - }, - ); + if !state.headers.contains_key(&symbol) { + state.headers.insert( + symbol.clone(), + Located::at(pattern.region, pat_type.clone()), + ); + } - constrain_pattern(var_store, state, loc_guard, pattern_expected); - } - None => { - constrain_pattern(var_store, state, pattern, pattern_expected); - } + field_types.insert(label.clone(), pat_type.clone()); + + // TODO investigate: shouldn't guard_var be constrained somewhere? + if let Some((_guard_var, loc_guard)) = guard { + constrain_pattern(var_store, state, loc_guard, expected); } state.vars.push(*var); - field_types.insert(label.clone(), pat_type); } let record_type = @@ -275,7 +271,9 @@ pub fn constrain_expr( symbol_for_lookup, .. } => { var_usage.register(symbol_for_lookup); - match var_usage.get_usage(symbol_for_lookup) { + let usage = var_usage.get_usage(symbol_for_lookup); + + match usage { Some(sharing::ReferenceCount::Shared) => { // the variable is used/consumed more than once, so it must be Shared let val_var = var_store.fresh(); diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index a4b82b8a49..bf91aca8f3 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -122,6 +122,7 @@ pub fn uniq_expr_with( let next_var = var_store1.into(); let subs1 = Subs::new(next_var); + // double check let var_store2 = VarStore::new(next_var); diff --git a/tests/test_infer.rs b/tests/test_infer.rs index 73f4b9dd12..14b94edd83 100644 --- a/tests/test_infer.rs +++ b/tests/test_infer.rs @@ -1068,6 +1068,24 @@ mod test_infer { ); } + #[test] + fn record_extraction() { + with_larger_debug_stack(|| { + infer_eq( + indoc!( + r#" + f = \x -> + when x is + { a, b } -> a + + f + "# + ), + "{ a : a, b : * }* -> a", + ); + }); + } + // currently doesn't work because of a parsing issue // @Foo x y isn't turned into Apply(@Foo, [x,y]) currently // #[test] diff --git a/tests/test_uniqueness_infer.rs b/tests/test_uniqueness_infer.rs index 43a3806f3e..9543a2be01 100644 --- a/tests/test_uniqueness_infer.rs +++ b/tests/test_uniqueness_infer.rs @@ -10,7 +10,7 @@ mod helpers; #[cfg(test)] mod test_infer_uniq { - use crate::helpers::uniq_expr; + use crate::helpers::{uniq_expr, with_larger_debug_stack}; use roc::infer::infer_expr; use roc::pretty_print_types::{content_to_string, name_all_type_vars}; @@ -920,4 +920,22 @@ mod test_infer_uniq { "Attr.Attr * { year : (Attr.Attr * Str) }{ name : (Attr.Attr * Str) }", ); } + + // #[test] + // fn record_extraction() { + // with_larger_debug_stack(|| { + // infer_eq( + // indoc!( + // r#" + // f = \x -> + // when x is + // { a, b } -> a + // + // f + // "# + // ), + // "Attr.Attr * (Attr.Attr u { a : Attr u a, b : * }* -> Attr u a)", + // ); + // }); + // } }