From a9cc9feaa64ba7642916c20b413ec06c88925f06 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doderlein Date: Thu, 22 Oct 2026 15:15:31 +0200 Subject: [PATCH] Add func<->con matching --- .../rascalcore/check/ATypeInstantiation.rsc | 12 +++++++++ .../check/tests/FunctionTCTests.rsc | 26 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeInstantiation.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeInstantiation.rsc index 07df4c713a2..be4920f81f4 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeInstantiation.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ATypeInstantiation.rsc @@ -192,6 +192,18 @@ public Bindings matchRascalTypeParams0(AType r, AType s, Bindings b) { return matchRascalTypeParams0(getFunctionReturnType(r), getFunctionReturnType(s), b); } + // A constructor can be used as a function (and vice versa during unification): + // match the parameter types with the fields, and the return type with the ADT + if ( isFunctionAType(r) && isConstructorAType(s) ) { + b = matchRascalTypeParams0(getFunctionArgumentTypesAsTuple(r), getConstructorArgumentTypesAsTuple(s), b); + return matchRascalTypeParams0(getFunctionReturnType(r), getConstructorResultType(s), b); + } + + if ( isConstructorAType(r) && isFunctionAType(s) ) { + b = matchRascalTypeParams0(getConstructorArgumentTypesAsTuple(r), getFunctionArgumentTypesAsTuple(s), b); + return matchRascalTypeParams0(getConstructorResultType(r), getFunctionReturnType(s), b); + } + // For tuples, check the arity then match the item types if ( isTupleAType(r) && isTupleAType(s) && getTupleFieldCount(r) == getTupleFieldCount(s) ) { rfields = getTupleFieldTypes(r); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/FunctionTCTests.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/FunctionTCTests.rsc index a68e56d33ce..eeee9601e22 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/FunctionTCTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/FunctionTCTests.rsc @@ -111,4 +111,28 @@ test bool SyntaxConstructorAsArgNotOk(){ void f(void(A) _) { } void main(){ f(a); }"); -} \ No newline at end of file +} +// https://github.com/usethesource/rascal/issues/2908 +test bool ADTConstructorAsArgToHigherOrderGenericFunctionOk(){ + return checkModuleOK(" + module ADTConstructorAsArgToHigherOrderGenericFunctionOk + data Msg = editField(str field, str val); + + &T(&V) partial(&T(&U0, &V) f, &U0 u0) = &T(&V v) { return f(u0, v); }; + + void show(Msg(str) _) { } + + void main(){ show(partial(editField, \"x\")); }"); +} + +test bool ADTConstructorAsArgToHigherOrderGenericFunctionNotOk(){ + return argumentMismatchInModule(" + module ADTConstructorAsArgToHigherOrderGenericFunctionNotOk + data Msg = editField(str field, str val); + + &T(&V) partial(&T(&U0, &V) f, &U0 u0) = &T(&V v) { return f(u0, v); }; + + void show(int(str) _) { } + + void main(){ show(partial(editField, \"x\")); }"); +}