Skip to content

Commit

Permalink
ast: When checking actual type par against constraints, do not walk t…
Browse files Browse the repository at this point in the history
…hrough inh chain of choice Fix #3362

Since choice types cannot be called, the result of a call to `choice X Y Z` is
`void`, which lead to choice types that inherit from choice to be accepted to
match any constraint. This patch fixes this by not walking through the parents
if the actual type parameter is a choice.

This also adds a regression test with the original code from #3362 and a minimalistic example.
  • Loading branch information
fridis committed Jul 15, 2024
1 parent 6608922 commit e36b98e
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 6 deletions.
11 changes: 5 additions & 6 deletions src/dev/flang/ast/AbstractType.java
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ public boolean constraintAssignableFrom(AbstractType actual)
var result = containsError() ||
actual.containsError() ||
this .compareTo(actual ) == 0 ||
this .compareTo(Types.resolved.t_Any ) == 0 ||
actual.isVoid();
if (!result && !isGenericArgument())
{
Expand All @@ -482,14 +483,12 @@ public boolean constraintAssignableFrom(AbstractType actual)
(actual.feature() != null || Errors.any());
if (actual.feature() != null)
{
if (actual.feature() == feature())
if (actual.feature() == feature() &&
genericsAssignable(actual)) // NYI: Check: What about open generics?
{
if (genericsAssignable(actual)) // NYI: Check: What about open generics?
{
result = true;
}
result = true;
}
if (!result)
else if (!actual.isChoice())
{
for (var p: actual.feature().inherits())
{
Expand Down
25 changes: 25 additions & 0 deletions tests/reg_issue3362/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion test Makefile
#
# -----------------------------------------------------------------------

override NAME = reg_issue3362
include ../simple_and_negative.mk
65 changes: 65 additions & 0 deletions tests/reg_issue3362/reg_issue3362.fz
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.


# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion test
#
# -----------------------------------------------------------------------

# Test choice type used as actual type parameter without matching the contstraing
#
reg_issue3362 is


# original example form issue #3362
#
base32_test is
my_c : choice String (array u8) is
mk_choice(x my_c) => x

# RFC 4618 test vectors
base32_test_vectors array (tuple my_c String) :=
[(mk_choice "fo", "MZXQ===="),
(mk_choice "foo", "MZXW6===")]

dummy_decode(arr array u8) outcome (array u8) => [0,0,0]

dec_test =>
for tup in base32_test_vectors do
(plain_expected, code) := tup
out :=
match dummy_decode code.utf8.as_array
arr array u8 =>
plain_actual := String.type.from_bytes arr
if plain_actual != plain_expected # 1. should flag an error: `choice String (array u8)` is not assignable to property.equatable
error "decoding $code produced '$plain_actual' but should have been '$plain_expected'"
else
outcome "ok"
e error => error "error in test data"
until !out.ok
out.err.as_string
else
"RFC 4648 test vectors are decoded correctly"
say dec_test


# minimalistic-example
#
c : choice i32 unit is
a c := 0
_ := 0 = a # 2. should flag an error: `choice i32 unit` is not assignable to property.equatable
15 changes: 15 additions & 0 deletions tests/reg_issue3362/reg_issue3362.fz.expected_err
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

--CURDIR--/reg_issue3362.fz:65:10: error 1: Incompatible type parameter
_ := 0 = a # 2. should flag an error: `choice i32 unit` is not assignable to property.equatable
---------^
formal type parameter 'T' with constraint 'property.equatable'
actual type parameter 'reg_issue3362.this.c'


--CURDIR--/reg_issue3362.fz:49:29: error 2: Incompatible type parameter
if plain_actual != plain_expected # 1. should flag an error: `choice String (array u8)` is not assignable to property.equatable
----------------------------^^
formal type parameter 'T' with constraint 'property.equatable'
actual type parameter 'reg_issue3362.this.my_c'

2 errors.
Empty file.

0 comments on commit e36b98e

Please sign in to comment.