mirror of
				https://github.com/roc-lang/roc.git
				synced 2025-11-03 22:13:35 +00:00 
			
		
		
		
	Constraining of list patterns
This commit is contained in:
		
							parent
							
								
									7b87d0093e
								
							
						
					
					
						commit
						9ab5d0efb8
					
				
					 4 changed files with 67 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -3,7 +3,7 @@ use crate::expr::{constrain_expr, Env};
 | 
			
		|||
use roc_can::constraint::{Constraint, Constraints};
 | 
			
		||||
use roc_can::expected::{Expected, PExpected};
 | 
			
		||||
use roc_can::pattern::Pattern::{self, *};
 | 
			
		||||
use roc_can::pattern::{DestructType, RecordDestruct};
 | 
			
		||||
use roc_can::pattern::{DestructType, ListPatterns, RecordDestruct};
 | 
			
		||||
use roc_collections::all::{HumanIndex, SendMap};
 | 
			
		||||
use roc_collections::VecMap;
 | 
			
		||||
use roc_module::ident::Lowercase;
 | 
			
		||||
| 
						 | 
				
			
			@ -513,12 +513,46 @@ pub fn constrain_pattern(
 | 
			
		|||
        List {
 | 
			
		||||
            list_var,
 | 
			
		||||
            elem_var,
 | 
			
		||||
            patterns: _,
 | 
			
		||||
            patterns:
 | 
			
		||||
                ListPatterns {
 | 
			
		||||
                    patterns,
 | 
			
		||||
                    opt_rest: _,
 | 
			
		||||
                },
 | 
			
		||||
        } => {
 | 
			
		||||
            for loc_pat in patterns.iter() {
 | 
			
		||||
                let expected =
 | 
			
		||||
                    PExpected::ForReason(PReason::ListElem, Type::Variable(*elem_var), region);
 | 
			
		||||
 | 
			
		||||
                constrain_pattern(
 | 
			
		||||
                    constraints,
 | 
			
		||||
                    env,
 | 
			
		||||
                    &loc_pat.value,
 | 
			
		||||
                    loc_pat.region,
 | 
			
		||||
                    expected,
 | 
			
		||||
                    state,
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let list_var_index = constraints.push_type(Type::Variable(*list_var));
 | 
			
		||||
            let solved_list = constraints.push_type(Type::Apply(
 | 
			
		||||
                Symbol::LIST_LIST,
 | 
			
		||||
                vec![Loc::at(region, Type::Variable(*elem_var))],
 | 
			
		||||
                region,
 | 
			
		||||
            ));
 | 
			
		||||
            let store_solved_list = constraints.store(solved_list, *list_var, file!(), line!());
 | 
			
		||||
 | 
			
		||||
            let expected = constraints.push_pat_expected_type(expected);
 | 
			
		||||
            let expected_constraint = constraints.pattern_presence(
 | 
			
		||||
                list_var_index,
 | 
			
		||||
                expected,
 | 
			
		||||
                PatternCategory::List,
 | 
			
		||||
                region,
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            state.vars.push(*list_var);
 | 
			
		||||
            state.vars.push(*elem_var);
 | 
			
		||||
 | 
			
		||||
            todo!();
 | 
			
		||||
            state.constraints.push(store_solved_list);
 | 
			
		||||
            state.constraints.push(expected_constraint);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        AppliedTag {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2160,6 +2160,7 @@ pub enum PReason {
 | 
			
		|||
        tag_name: TagName,
 | 
			
		||||
        index: HumanIndex,
 | 
			
		||||
    },
 | 
			
		||||
    ListElem,
 | 
			
		||||
    PatternGuard,
 | 
			
		||||
    OptionalField,
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1945,8 +1945,8 @@ fn to_pattern_report<'b>(
 | 
			
		|||
                    severity: Severity::RuntimeError,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            PReason::TagArg { .. } | PReason::PatternGuard => {
 | 
			
		||||
                unreachable!("I didn't think this could trigger. Please tell Folkert about it!")
 | 
			
		||||
            PReason::TagArg { .. } | PReason::PatternGuard | PReason::ListElem => {
 | 
			
		||||
                internal_error!("We didn't think this could trigger. Please tell us about it on Zulip if it does!")
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11821,4 +11821,30 @@ All branches in an `if` must have the same type!
 | 
			
		|||
    I would have to crash if I saw one of those! Add branches for them!
 | 
			
		||||
    "###
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    test_report!(
 | 
			
		||||
        #[ignore = "must implement exhaustiveness sketching for lists first"]
 | 
			
		||||
        mismatch_within_list_pattern,
 | 
			
		||||
        indoc!(
 | 
			
		||||
            r#"
 | 
			
		||||
            when [] is
 | 
			
		||||
                [A, 1u8] -> ""
 | 
			
		||||
            "#
 | 
			
		||||
        ),
 | 
			
		||||
    @r###"
 | 
			
		||||
    "###
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    test_report!(
 | 
			
		||||
        #[ignore = "must implement exhaustiveness sketching for lists first"]
 | 
			
		||||
        mismatch_list_pattern_vs_condition,
 | 
			
		||||
        indoc!(
 | 
			
		||||
            r#"
 | 
			
		||||
            when [A, B] is
 | 
			
		||||
                ["foo", "bar"] -> ""
 | 
			
		||||
            "#
 | 
			
		||||
        ),
 | 
			
		||||
    @r###"
 | 
			
		||||
    "###
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue