From 404714445e5c6ef222f3a7b9d86ef642a943b392 Mon Sep 17 00:00:00 2001 From: Joe Eli McIlvain Date: Tue, 17 Apr 2018 20:47:18 -0700 Subject: [PATCH] Fix tuple pattern matching issue where some elements would violate caps. When pattern-matching tuples that have the same number of elements, ponyc was treating the entire match as violating capabilities when only one of the elements was violating. In truth we should be able to recognize that tuples are distinct from the other elements. This patch fixes `is_tuple_match_tuple` to return MATCHTYPE_REJECT as soon as any pairwise element comparison returns MATCHTYPE_REJECT. The fix was pinpointed by @Praetonus when I discussed this issue with him. --- src/libponyc/type/matchtype.c | 2 +- test/libponyc/matchtype.cc | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libponyc/type/matchtype.c b/src/libponyc/type/matchtype.c index 3142edd80d..8b9e312dbb 100644 --- a/src/libponyc/type/matchtype.c +++ b/src/libponyc/type/matchtype.c @@ -273,7 +273,7 @@ static matchtype_t is_tuple_match_tuple(ast_t* operand, ast_t* pattern, break; } - if(ok == MATCHTYPE_DENY) + if(ok != MATCHTYPE_ACCEPT) break; operand_child = ast_sibling(operand_child); diff --git a/test/libponyc/matchtype.cc b/test/libponyc/matchtype.cc index ce7ad58769..89a331bbd0 100644 --- a/test/libponyc/matchtype.cc +++ b/test/libponyc/matchtype.cc @@ -309,6 +309,7 @@ TEST_F(MatchTypeTest, Tuples) "interface Test\n" " fun z(c1: C1, c2: C2, c3: C3, t1: T1, t2: T2,\n" " c1c1: (C1, C1), c1c2: (C1, C2), c1c3: (C1, C3),\n" + " c2i1: (C2, I1), c3i1tag: (C3, I1 tag),\n" " t1t2: (T1, T2), i1: I1, i2: I2)"; TEST_COMPILE(src); @@ -328,6 +329,11 @@ TEST_F(MatchTypeTest, Tuples) ASSERT_EQ( MATCHTYPE_REJECT, is_matchtype(type_of("i2"), type_of("c1c1"), NULL, &opt)); + ASSERT_EQ( + MATCHTYPE_REJECT, is_matchtype(type_of("c2i1"), type_of("c3i1tag"), NULL, &opt)); + ASSERT_EQ( + MATCHTYPE_REJECT, is_matchtype(type_of("c3i1tag"), type_of("c2i1"), NULL, &opt)); + // We can't make types with don't cares in as the type of a parameter. Modify // t1t2 instead. ast_t* t1t2 = type_of("t1t2");