Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,16 @@ void resetClosureCounter(){
}

str generateClosureName() = "$CLOSURE_<nextClosure()>";

AType getInstantiated(Tree tree, Solver s) {
AType t = s.getType(tree);
if (isInstantiated(t)) {
return t;
} else {
throw TypeUnavailable();
}
}

bool isInstantiated(AType t) {
return /aparameter(_, _) !:= t;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,8 @@ void collect(current: (Expression) `<Expression expression> . <Name field>`, Col
AType(Solver s){
expType = s.getType(expression);
fieldType = s.getType(field);
// expType = getInstantiated(expression, s);
// fieldType = getInstantiated(field, s);

if(isVoidAType(expType)) s.report(error(expression, "Base expression of field selection should not have type `void`"));
if(overloadedAType(rel[loc, IdRole, AType] overloads) := expType){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ void(Solver) makeVarInitRequirement(Variable var)
catch invalidMatch(str reason):
s.report(error(var.initial, reason));

// if (isInstantiated(varTypeU) && !isInstantiated(initialTypeU)) {
// println("NOT READY -- <var.name>: <varType> -- <var.initial>: <initialType>");
// facts = s.getFacts();
// for (f <- facts, f.offset?, f.offset >= 130) {
// println(" - <f>: <facts[f]>");
// }
// throw TypeUnavailable();
// }

initialTypeU = instantiateRascalTypeParameters(var, initialTypeU, bindings, s);
if(s.isFullyInstantiated(initialTypeU)){
if(overloadedAType(overloads) := initialTypeU){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,73 @@ test bool Escapes2() = checkModuleOK("

// ---- type parameters -------------------------------------------------------

test bool ADTWithTypeParameter() = checkModuleOK("
module ADTWithTypeParameter
data D[&T] = d1(&T n);
test bool Box() = checkModuleOK("
module Box
data Box[&T] = box(&T v);
&T unbox(Box[&T] b) = b.v;
");

test bool NumBox() = checkModuleOK("
module NumBox
data NumBox[&T \<: num] = box(&T v);

&T \<: num unboxAndSum(NumBox[&T \<: num] box1, NumBox[&T \<: num] box2) {
&T v1 = box1.v;
&T v2 = box2.v;
return v1 + v2;
}
");

test bool ADTWithTypeParameter1() = checkModuleOK("
module ADTWithTypeParameter1
data D[&T] = d(&T n);
int n = d(5).n;
");

test bool ADTWithTypeParameter2() = checkModuleOK("
module Bar
data D[&T] = d(&T n);
int f() {
n1 = d(5).n;
n2 = n1;
n3 = n2;
return n3 + 5;
}
");

test bool ADTWithTypeParameter2ButDifferentModuleName() = checkModuleOK("
module Foo
data D[&T] = d(&T n);
int f() {
n1 = d(5).n;
n2 = n1;
n3 = n2;
return n3 + 5;
}
");

/*
* `d(5).n` kan van een ongeinstantieerd type zijn. Of dit toegestaan is, hangt
* in het algemeen af van de context (onduidelijk op basis van alleen de field
* access).
*
* Maw, je probeert het type te berekenen van een field access. Er komt een
* ongeinstantieerd type uit. Is dat ok? Onmogelijk om te zeggen op basis van
* alleen de access. In het geval van `Box` en `NumBox` is het ok (i.e., het
* type blijft altijd ongeinstantieerd). In het geval van `Foo` is het niet ok
* (i.e., het type wordt later geinstantieerd, en die instantiatie zou door
* moeten stromen naar afhankelijke locaties).
*
* De vraag is nu: kun je ervoor zorgen, op een of andere manier, dat `calc(useViaType, ...) pas wordt geevalueerd na `calc(n, ...)`?
* Bijvoorbeeld: type van de constructor pas kunnen berekenen als het type van de typeparameter bekend is?
*/

test bool ADTWithTypeParameter3() = checkModuleOK("
module ADTWithTypeParameter3
data D1[&T] = d1(D2[&T] inner);
data D2[&T] = d2(&T n);
D1[int] outer = d1(d2(5));
int n = outer.inner.n;
");

test bool UndefinedParameter() = unexpectedTypeInModule("
Expand Down Expand Up @@ -484,7 +548,7 @@ test bool ADTWithTypeParameterAndKW2() = checkModuleOK("
void f() { D[int] x = d1(10); int m = x.kw; }
");

test bool ADTWithTypeParameterAndKW3() = checkModuleOK("
test bool ADTWithTypeParameterAndKW3() = unexpectedTypeInModule("
module ADTWithTypeParameterAndKW3
data D[&T] = d1(&T n, &T kw = n);
void f() { D[int] x = d1(10); str m = x.kw; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ bool checkModuleAndFilter(list[loc] mlocs, list[str] expected, bool matchAll = f
if(matchAll) {
return all(e <- expected, e in matched);
}
iprintln(msgs);
throw abbrev("<msgs>");
}

Expand Down Expand Up @@ -325,7 +326,8 @@ list[str] unexpectedTypeMsgs = [
"Expected a binary relation, found _",
"Constructor _ is overloaded",
"Expression _ is overloaded",
"Base expression _ of field selection should have a unique type"
"Base expression _ of field selection should have a unique type",
"Invalid initialization of ; type of one or more subparts could not be inferred"
];

bool unexpectedTypeInModule(str moduleText, PathConfig pathConfig = getDefaultTestingPathConfig())
Expand Down
Loading