mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
add whole_var to tag union/record
the existing var is for the extension (ext_var). during mono we need the whole type to look up the layout, so store that as well
This commit is contained in:
parent
129be86233
commit
2e697ee8f9
2 changed files with 47 additions and 19 deletions
|
@ -662,13 +662,13 @@ fn pattern_to_vars_by_symbol(
|
||||||
vars_by_symbol.insert(symbol.clone(), expr_var);
|
vars_by_symbol.insert(symbol.clone(), expr_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppliedTag(_, _, arguments) => {
|
AppliedTag { arguments, .. } => {
|
||||||
for (var, nested) in arguments {
|
for (var, nested) in arguments {
|
||||||
pattern_to_vars_by_symbol(vars_by_symbol, &nested.value, *var);
|
pattern_to_vars_by_symbol(vars_by_symbol, &nested.value, *var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordDestructure(_, destructs) => {
|
RecordDestructure { destructs, .. } => {
|
||||||
for destruct in destructs {
|
for destruct in destructs {
|
||||||
vars_by_symbol.insert(destruct.value.symbol.clone(), destruct.value.var);
|
vars_by_symbol.insert(destruct.value.symbol.clone(), destruct.value.var);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,21 @@ use roc_types::subs::{VarStore, Variable};
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Pattern {
|
pub enum Pattern {
|
||||||
Identifier(Symbol),
|
Identifier(Symbol),
|
||||||
AppliedTag(Variable, TagName, Vec<(Variable, Located<Pattern>)>),
|
AppliedTag {
|
||||||
|
whole_var: Variable,
|
||||||
|
ext_var: Variable,
|
||||||
|
tag_name: TagName,
|
||||||
|
arguments: Vec<(Variable, Located<Pattern>)>,
|
||||||
|
},
|
||||||
|
RecordDestructure {
|
||||||
|
whole_var: Variable,
|
||||||
|
ext_var: Variable,
|
||||||
|
destructs: Vec<Located<RecordDestruct>>,
|
||||||
|
},
|
||||||
IntLiteral(i64),
|
IntLiteral(i64),
|
||||||
NumLiteral(Variable, i64),
|
NumLiteral(Variable, i64),
|
||||||
FloatLiteral(f64),
|
FloatLiteral(f64),
|
||||||
StrLiteral(Box<str>),
|
StrLiteral(Box<str>),
|
||||||
RecordDestructure(Variable, Vec<Located<RecordDestruct>>),
|
|
||||||
Underscore,
|
Underscore,
|
||||||
|
|
||||||
// Runtime Exceptions
|
// Runtime Exceptions
|
||||||
|
@ -51,12 +60,12 @@ pub fn symbols_from_pattern_help(pattern: &Pattern, symbols: &mut Vec<Symbol>) {
|
||||||
symbols.push(symbol.clone());
|
symbols.push(symbol.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
AppliedTag(_, _, arguments) => {
|
AppliedTag { arguments, .. } => {
|
||||||
for (_, nested) in arguments {
|
for (_, nested) in arguments {
|
||||||
symbols_from_pattern_help(&nested.value, symbols);
|
symbols_from_pattern_help(&nested.value, symbols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecordDestructure(_, destructs) => {
|
RecordDestructure { destructs, .. } => {
|
||||||
for destruct in destructs {
|
for destruct in destructs {
|
||||||
symbols.push(destruct.value.symbol.clone());
|
symbols.push(destruct.value.symbol.clone());
|
||||||
}
|
}
|
||||||
|
@ -103,17 +112,23 @@ pub fn canonicalize_pattern<'a>(
|
||||||
},
|
},
|
||||||
GlobalTag(name) => {
|
GlobalTag(name) => {
|
||||||
// Canonicalize the tag's name.
|
// Canonicalize the tag's name.
|
||||||
Pattern::AppliedTag(var_store.fresh(), TagName::Global((*name).into()), vec![])
|
Pattern::AppliedTag {
|
||||||
|
whole_var: var_store.fresh(),
|
||||||
|
ext_var: var_store.fresh(),
|
||||||
|
tag_name: TagName::Global((*name).into()),
|
||||||
|
arguments: vec![],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PrivateTag(name) => {
|
PrivateTag(name) => {
|
||||||
let ident_id = env.ident_ids.get_or_insert(&(*name).into());
|
let ident_id = env.ident_ids.get_or_insert(&(*name).into());
|
||||||
|
|
||||||
// Canonicalize the tag's name.
|
// Canonicalize the tag's name.
|
||||||
Pattern::AppliedTag(
|
Pattern::AppliedTag {
|
||||||
var_store.fresh(),
|
whole_var: var_store.fresh(),
|
||||||
TagName::Private(Symbol::new(env.home, ident_id)),
|
ext_var: var_store.fresh(),
|
||||||
vec![],
|
tag_name: TagName::Private(Symbol::new(env.home, ident_id)),
|
||||||
)
|
arguments: vec![],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Apply(tag, patterns) => {
|
Apply(tag, patterns) => {
|
||||||
let tag_name = match tag.value {
|
let tag_name = match tag.value {
|
||||||
|
@ -141,7 +156,12 @@ pub fn canonicalize_pattern<'a>(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern::AppliedTag(var_store.fresh(), tag_name, can_patterns)
|
Pattern::AppliedTag {
|
||||||
|
whole_var: var_store.fresh(),
|
||||||
|
ext_var: var_store.fresh(),
|
||||||
|
tag_name,
|
||||||
|
arguments: can_patterns,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatLiteral(ref string) => match pattern_type {
|
FloatLiteral(ref string) => match pattern_type {
|
||||||
|
@ -208,7 +228,8 @@ pub fn canonicalize_pattern<'a>(
|
||||||
}
|
}
|
||||||
RecordDestructure(patterns) => {
|
RecordDestructure(patterns) => {
|
||||||
let ext_var = var_store.fresh();
|
let ext_var = var_store.fresh();
|
||||||
let mut fields = Vec::with_capacity(patterns.len());
|
let whole_var = var_store.fresh();
|
||||||
|
let mut destructs = Vec::with_capacity(patterns.len());
|
||||||
let mut opt_erroneous = None;
|
let mut opt_erroneous = None;
|
||||||
|
|
||||||
for loc_pattern in *patterns {
|
for loc_pattern in *patterns {
|
||||||
|
@ -221,7 +242,7 @@ pub fn canonicalize_pattern<'a>(
|
||||||
region,
|
region,
|
||||||
) {
|
) {
|
||||||
Ok(symbol) => {
|
Ok(symbol) => {
|
||||||
fields.push(Located {
|
destructs.push(Located {
|
||||||
region: loc_pattern.region,
|
region: loc_pattern.region,
|
||||||
value: RecordDestruct {
|
value: RecordDestruct {
|
||||||
var: var_store.fresh(),
|
var: var_store.fresh(),
|
||||||
|
@ -262,7 +283,7 @@ pub fn canonicalize_pattern<'a>(
|
||||||
loc_guard.region,
|
loc_guard.region,
|
||||||
);
|
);
|
||||||
|
|
||||||
fields.push(Located {
|
destructs.push(Located {
|
||||||
region: loc_pattern.region,
|
region: loc_pattern.region,
|
||||||
value: RecordDestruct {
|
value: RecordDestruct {
|
||||||
var: var_store.fresh(),
|
var: var_store.fresh(),
|
||||||
|
@ -292,7 +313,11 @@ pub fn canonicalize_pattern<'a>(
|
||||||
|
|
||||||
// If we encountered an erroneous pattern (e.g. one with shadowing),
|
// If we encountered an erroneous pattern (e.g. one with shadowing),
|
||||||
// use the resulting RuntimeError. Otherwise, return a successful record destructure.
|
// use the resulting RuntimeError. Otherwise, return a successful record destructure.
|
||||||
opt_erroneous.unwrap_or_else(|| Pattern::RecordDestructure(ext_var, fields))
|
opt_erroneous.unwrap_or_else(|| Pattern::RecordDestructure {
|
||||||
|
whole_var,
|
||||||
|
ext_var,
|
||||||
|
destructs,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
RecordField(_name, _loc_pattern) => {
|
RecordField(_name, _loc_pattern) => {
|
||||||
unreachable!("should have been handled in RecordDestructure");
|
unreachable!("should have been handled in RecordDestructure");
|
||||||
|
@ -345,12 +370,15 @@ fn add_bindings_from_patterns(
|
||||||
Identifier(symbol) => {
|
Identifier(symbol) => {
|
||||||
answer.push((*symbol, *region));
|
answer.push((*symbol, *region));
|
||||||
}
|
}
|
||||||
AppliedTag(_, _, loc_args) => {
|
AppliedTag {
|
||||||
|
arguments: loc_args,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
for (_, loc_arg) in loc_args {
|
for (_, loc_arg) in loc_args {
|
||||||
add_bindings_from_patterns(&loc_arg.region, &loc_arg.value, scope, answer);
|
add_bindings_from_patterns(&loc_arg.region, &loc_arg.value, scope, answer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecordDestructure(_, destructs) => {
|
RecordDestructure { destructs, .. } => {
|
||||||
for Located {
|
for Located {
|
||||||
region,
|
region,
|
||||||
value: RecordDestruct { symbol, .. },
|
value: RecordDestruct { symbol, .. },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue