Merge pull request #150 from HigherOrderCO/bug/sc-404/fix-string-list-removal-when-only-declared

[sc-404] Fix string/list removal when only declared on match arms
This commit is contained in:
Nicolas Abril 2024-01-25 15:26:08 +01:00 committed by GitHub
commit 074f043e69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 74 additions and 10 deletions

View File

@ -617,6 +617,27 @@ impl Pattern {
set.into_iter().flat_map(|a| a.as_mut())
}
pub fn ctrs(&self) -> impl DoubleEndedIterator<Item = &Name> {
fn go<'a>(pat: &'a Pattern, set: &mut Vec<&'a Name>) {
match pat {
Pattern::Ctr(nam, pats) => {
set.push(nam);
pats.iter().for_each(|pat| go(pat, set));
}
Pattern::List(pats) => pats.iter().for_each(|pat| go(pat, set)),
Pattern::Tup(fst, snd) => {
go(fst, set);
go(snd, set);
}
Pattern::Var(_) => {},
Pattern::Num(_) => {}
}
}
let mut set = Vec::new();
go(self, &mut set);
set.into_iter()
}
pub fn is_detached_num_match(&self) -> bool {
if let Pattern::Num(num) = self {
match num {

View File

@ -66,12 +66,12 @@ impl Term {
fst_uses || snd_uses
}
Term::Match { scrutinee, arms } => {
let mut used = false;
let scrutinee_used = scrutinee.encode_lists();
for arm in arms {
used |= arm.1.encode_lists();
let mut used = scrutinee.encode_lists();
for (pat, arm) in arms {
used |= pat.names().chain(pat.ctrs()).any(|Name(n)| matches!(n.as_str(), LCONS | LNIL));
used |= arm.encode_lists();
}
scrutinee_used || used
used
}
Term::Var { nam: Name(nam) } => nam == LCONS || nam == LNIL,
Term::Lnk { .. } | Term::Ref { .. } | Term::Num { .. } | Term::Str { .. } | Term::Era => false,

View File

@ -61,12 +61,12 @@ impl Term {
fst_uses || snd_uses
}
Term::Match { arms, scrutinee } => {
let mut used = false;
let scrutinee_used = scrutinee.encode_str();
for arm in arms {
used |= arm.1.encode_str();
let mut used = scrutinee.encode_str();
for (pat, arm) in arms {
used |= pat.names().chain(pat.ctrs()).any(|Name(n)| matches!(n.as_str(), SCONS | SNIL));
used |= arm.encode_str();
}
scrutinee_used || used
used
}
Term::List { els } => {
let mut used = false;

View File

@ -0,0 +1,10 @@
main = @a @b
let a = match a {
SCons: 1
SNil : 2
};
let b = match b {
(LCons h t): 1
(LNil) : 2
};
(a, b)

View File

@ -0,0 +1,33 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared.hvm
---
(main) = λa λb let a = (main$match$1 a); let b = (main$match$2 b); (a, b)
(LCons) = λhead λtail #List λLCons #List λLNil #List.LCons.tail (#List.LCons.head (LCons head) tail)
(LNil) = #List λLCons #List λLNil LNil
(SCons) = λhead λtail #String λSCons #String λSNil #String.SCons.tail (#String.SCons.head (SCons head) tail)
(SNil) = #String λSCons #String λSNil SNil
(main$match$1) = λx #String (x main$match$1$PSCons main$match$1$PSNil)
(main$match$2) = λx #List (x main$match$2$PLCons main$match$2$PLNil)
(main$match$1$R0) = λa.head λa.tail 1
(main$match$1$R1) = 2
(main$match$1$PSCons) = #String.SCons.head λy0 #String.SCons.tail λy1 (main$match$1$R0 * *)
(main$match$1$PSNil) = main$match$1$R1
(main$match$2$R0) = λh λt 1
(main$match$2$R1) = 2
(main$match$2$PLCons) = #List.LCons.head λy0 #List.LCons.tail λy1 (main$match$2$R0 * *)
(main$match$2$PLNil) = main$match$2$R1