mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 05:34:11 +03:00
can for normal (no-list) as
This commit is contained in:
parent
06cfdd71cc
commit
905341d849
@ -654,6 +654,7 @@ fn deep_copy_pattern_help<C: CopyEnv>(
|
||||
|
||||
match pat {
|
||||
Identifier(s) => Identifier(*s),
|
||||
As(subpattern, s) => As(Box::new(subpattern.map(|p| go_help!(p))), *s),
|
||||
AppliedTag {
|
||||
whole_var,
|
||||
ext_var,
|
||||
|
@ -431,6 +431,9 @@ fn pattern<'a>(
|
||||
| AbilityMemberSpecialization {
|
||||
specializes: sym, ..
|
||||
} => pp_sym(c, f, *sym),
|
||||
As(subpattern, symbol) => pattern(c, prec, f, &subpattern.value)
|
||||
.append(f.text(" as "))
|
||||
.append(pp_sym(c, f, *symbol)),
|
||||
AppliedTag {
|
||||
tag_name,
|
||||
arguments,
|
||||
|
@ -1967,6 +1967,12 @@ fn pattern_to_vars_by_symbol(
|
||||
vars_by_symbol.insert(*symbol, expr_var);
|
||||
}
|
||||
|
||||
As(subpattern, symbol) => {
|
||||
vars_by_symbol.insert(*symbol, expr_var);
|
||||
|
||||
pattern_to_vars_by_symbol(vars_by_symbol, &subpattern.value, expr_var);
|
||||
}
|
||||
|
||||
AbilityMemberSpecialization {
|
||||
ident,
|
||||
specializes: _,
|
||||
|
@ -301,6 +301,7 @@ fn sketch_pattern(pattern: &crate::pattern::Pattern) -> SketchedPattern {
|
||||
use SketchedPattern as SP;
|
||||
|
||||
match pattern {
|
||||
As(subpattern, _) => sketch_pattern(&subpattern.value),
|
||||
&NumLiteral(_, _, IntValue::I128(n), _) | &IntLiteral(_, _, _, IntValue::I128(n), _) => {
|
||||
SP::Literal(Literal::Int(n))
|
||||
}
|
||||
|
@ -929,6 +929,14 @@ fn fix_values_captured_in_closure_pattern(
|
||||
);
|
||||
}
|
||||
}
|
||||
As(subpattern, _) => {
|
||||
fix_values_captured_in_closure_pattern(
|
||||
&mut subpattern.value,
|
||||
no_capture_symbols,
|
||||
closure_captures,
|
||||
);
|
||||
}
|
||||
|
||||
Identifier(_)
|
||||
| NumLiteral(..)
|
||||
| IntLiteral(..)
|
||||
|
@ -22,6 +22,7 @@ use roc_types::types::{LambdaSet, OptAbleVar, PatternCategory, Type};
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Pattern {
|
||||
Identifier(Symbol),
|
||||
As(Box<Loc<Pattern>>, Symbol),
|
||||
AppliedTag {
|
||||
whole_var: Variable,
|
||||
ext_var: Variable,
|
||||
@ -94,6 +95,7 @@ impl Pattern {
|
||||
use Pattern::*;
|
||||
match self {
|
||||
Identifier(_) => None,
|
||||
As(pattern, _) => pattern.value.opt_var(),
|
||||
|
||||
AppliedTag { whole_var, .. } => Some(*whole_var),
|
||||
UnwrappedOpaque { whole_var, .. } => Some(*whole_var),
|
||||
@ -129,6 +131,7 @@ impl Pattern {
|
||||
| MalformedPattern(..)
|
||||
| AbilityMemberSpecialization { .. } => true,
|
||||
RecordDestructure { destructs, .. } => destructs.is_empty(),
|
||||
As(pattern, _identifier) => pattern.value.surely_exhaustive(),
|
||||
List { patterns, .. } => patterns.surely_exhaustive(),
|
||||
AppliedTag { .. }
|
||||
| NumLiteral(..)
|
||||
@ -151,6 +154,7 @@ impl Pattern {
|
||||
|
||||
match self {
|
||||
Identifier(_) => C::PatternDefault,
|
||||
As(pattern, _) => pattern.value.category(),
|
||||
|
||||
AppliedTag { tag_name, .. } => C::Ctor(tag_name.clone()),
|
||||
UnwrappedOpaque { opaque, .. } => C::Opaque(*opaque),
|
||||
@ -832,6 +836,10 @@ impl<'a> BindingsFromPattern<'a> {
|
||||
} => {
|
||||
return Some((*symbol, loc_pattern.region));
|
||||
}
|
||||
As(pattern, symbol) => {
|
||||
stack.push(Pattern(pattern));
|
||||
return Some((*symbol, loc_pattern.region));
|
||||
}
|
||||
AppliedTag {
|
||||
arguments: loc_args,
|
||||
..
|
||||
|
@ -476,6 +476,9 @@ pub fn walk_pattern<V: Visitor>(visitor: &mut V, pattern: &Pattern) {
|
||||
|
||||
match pattern {
|
||||
Identifier(..) => { /* terminal */ }
|
||||
As(subpattern, _symbol) => {
|
||||
visitor.visit_pattern(&subpattern.value, subpattern.region, None)
|
||||
}
|
||||
AppliedTag { arguments, .. } => arguments
|
||||
.iter()
|
||||
.for_each(|(v, lp)| visitor.visit_pattern(&lp.value, lp.region, Some(*v))),
|
||||
|
@ -60,16 +60,31 @@ fn headers_from_annotation_help(
|
||||
match pattern {
|
||||
Identifier(symbol)
|
||||
| Shadowed(_, _, symbol)
|
||||
// TODO(abilities): handle linking the member def to the specialization ident
|
||||
| AbilityMemberSpecialization {
|
||||
ident: symbol,
|
||||
// TODO(abilities): handle linking the member def to the specialization ident
|
||||
specializes: _,
|
||||
} => {
|
||||
let annotation_index = { let typ = types.from_old_type(annotation.value); constraints.push_type(types, typ) };
|
||||
let annotation_index = {
|
||||
let typ = types.from_old_type(annotation.value);
|
||||
constraints.push_type(types, typ)
|
||||
};
|
||||
let typ = Loc::at(annotation.region, annotation_index);
|
||||
headers.insert(*symbol, typ);
|
||||
true
|
||||
}
|
||||
|
||||
As(subpattern, symbol) => {
|
||||
let annotation_index = {
|
||||
let typ = types.from_old_type(annotation.value);
|
||||
constraints.push_type(types, typ)
|
||||
};
|
||||
let typ = Loc::at(annotation.region, annotation_index);
|
||||
headers.insert(*symbol, typ);
|
||||
|
||||
headers_from_annotation_help(types, constraints, &subpattern.value, annotation, headers)
|
||||
}
|
||||
|
||||
Underscore
|
||||
| MalformedPattern(_, _)
|
||||
| UnsupportedPattern(_)
|
||||
@ -93,7 +108,10 @@ fn headers_from_annotation_help(
|
||||
// `{ x ? 0 } = rec` or `{ x: 5 } -> ...` in all cases
|
||||
// the type of `x` within the binding itself is the same.
|
||||
if let Some(field_type) = fields.get(&destruct.label) {
|
||||
let field_type_index = { let typ = types.from_old_type(&field_type.as_inner().clone()); constraints.push_type(types, typ) };
|
||||
let field_type_index = {
|
||||
let typ = types.from_old_type(&field_type.as_inner().clone());
|
||||
constraints.push_type(types, typ)
|
||||
};
|
||||
headers.insert(
|
||||
destruct.symbol,
|
||||
Loc::at(annotation.region, field_type_index),
|
||||
@ -114,7 +132,7 @@ fn headers_from_annotation_help(
|
||||
// \[..] -> <body>
|
||||
// which does not introduce any symbols.
|
||||
false
|
||||
},
|
||||
}
|
||||
|
||||
AppliedTag {
|
||||
tag_name,
|
||||
@ -165,7 +183,10 @@ fn headers_from_annotation_help(
|
||||
&& type_arguments.len() == pat_type_arguments.len()
|
||||
&& lambda_set_variables.len() == pat_lambda_set_variables.len() =>
|
||||
{
|
||||
let annotation_index = { let typ = types.from_old_type(annotation.value); constraints.push_type(types, typ) };
|
||||
let annotation_index = {
|
||||
let typ = types.from_old_type(annotation.value);
|
||||
constraints.push_type(types, typ)
|
||||
};
|
||||
let typ = Loc::at(annotation.region, annotation_index);
|
||||
headers.insert(*opaque, typ);
|
||||
|
||||
@ -183,6 +204,32 @@ fn headers_from_annotation_help(
|
||||
}
|
||||
}
|
||||
|
||||
fn constrain_pattern_symbol(
|
||||
types: &mut Types,
|
||||
constraints: &mut Constraints,
|
||||
region: Region,
|
||||
expected: PExpectedTypeIndex,
|
||||
state: &mut PatternState,
|
||||
symbol: Symbol,
|
||||
) {
|
||||
let expected = &constraints[expected];
|
||||
let type_index = *expected.get_type_ref();
|
||||
|
||||
if could_be_a_tag_union(types, type_index) {
|
||||
state
|
||||
.delayed_is_open_constraints
|
||||
.push(constraints.is_open_type(type_index));
|
||||
}
|
||||
|
||||
state.headers.insert(
|
||||
symbol,
|
||||
Loc {
|
||||
region,
|
||||
value: type_index,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// This accepts PatternState (rather than returning it) so that the caller can
|
||||
/// initialize the Vecs in PatternState using with_capacity
|
||||
/// based on its knowledge of their lengths.
|
||||
@ -215,22 +262,21 @@ pub fn constrain_pattern(
|
||||
}
|
||||
|
||||
Identifier(symbol) | Shadowed(_, _, symbol) => {
|
||||
let expected = &constraints[expected];
|
||||
let type_index = *expected.get_type_ref();
|
||||
constrain_pattern_symbol(types, constraints, region, expected, state, *symbol);
|
||||
}
|
||||
|
||||
if could_be_a_tag_union(types, type_index) {
|
||||
state
|
||||
.delayed_is_open_constraints
|
||||
.push(constraints.is_open_type(type_index));
|
||||
}
|
||||
As(subpattern, symbol) => {
|
||||
constrain_pattern_symbol(types, constraints, region, expected, state, *symbol);
|
||||
|
||||
state.headers.insert(
|
||||
*symbol,
|
||||
Loc {
|
||||
region,
|
||||
value: type_index,
|
||||
},
|
||||
);
|
||||
constrain_pattern(
|
||||
types,
|
||||
constraints,
|
||||
env,
|
||||
&subpattern.value,
|
||||
subpattern.region,
|
||||
expected,
|
||||
state,
|
||||
)
|
||||
}
|
||||
|
||||
AbilityMemberSpecialization {
|
||||
|
@ -2870,6 +2870,8 @@ fn pattern_to_when<'a>(
|
||||
(*new_symbol, Loc::at_zero(RuntimeError(error)))
|
||||
}
|
||||
|
||||
As(_, _) => todo!("as bindings are not supported yet"),
|
||||
|
||||
UnsupportedPattern(region) => {
|
||||
// create the runtime error here, instead of delegating to When.
|
||||
// UnsupportedPattern should then never occur in When
|
||||
@ -9398,6 +9400,7 @@ fn from_can_pattern_help<'a>(
|
||||
match can_pattern {
|
||||
Underscore => Ok(Pattern::Underscore),
|
||||
Identifier(symbol) => Ok(Pattern::Identifier(*symbol)),
|
||||
As(_, _) => todo!(),
|
||||
AbilityMemberSpecialization { ident, .. } => Ok(Pattern::Identifier(*ident)),
|
||||
IntLiteral(var, _, int_str, int, _bound) => Ok(make_num_literal_pattern(
|
||||
env,
|
||||
|
Loading…
Reference in New Issue
Block a user