From 72df8b4336a54644924552d93305e07e251a69a0 Mon Sep 17 00:00:00 2001 From: paulklint Date: Sat, 18 Apr 2026 10:45:03 +0200 Subject: [PATCH 01/23] Added visualization of calculator/requirement dependencies and added dependencies - Added visualization of calculator/requirement dependencies in TModel (will be moved later to TypePal) - Added several dependencies all related to TypeParameters --- .../rascalcore/check/CollectDeclaration.rsc | 2 +- .../lang/rascalcore/check/CollectPattern.rsc | 37 ++-- .../lang/rascalcore/check/CollectType.rsc | 11 +- .../rascalcore/check/DependencyViewer.rsc | 208 ++++++++++++++++++ .../lang/rascalcore/check/RascalConfig.rsc | 3 + .../lang/rascalcore/compile/Examples/Tst5.rsc | 9 +- .../lang/rascalcore/compile/Examples/Tst7.rsc | 11 + 7 files changed, 257 insertions(+), 24 deletions(-) create mode 100644 src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc create mode 100644 src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index b50f602844d..493e2019f3d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -624,7 +624,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, [], + c.calculate("formals", parameters, [*formals,*kwFormals], AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc index 1844b2549ba..471af5293a3 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc @@ -85,6 +85,21 @@ void collect(current: (Pattern) `[ <{Pattern ","}* elements0> ]`, Collector c){ c.pop(patternContainer); } +list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){ + if(/TypeVar _ := tp){ + functionScopes = c.getScopeInfo(functionScope()); + if(!isEmpty(functionScopes)){ + for(<_, scopeInfo> <- functionScopes){ + if(signatureInfo(Type returnType) := scopeInfo){ + return [tp, returnType]; + } else { + throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: "); + } + } + } + } + return [tp]; +} // ---- typed variable pattern void collect(current: (Pattern) ` `, Collector c){ @@ -92,21 +107,9 @@ void collect(current: (Pattern) ` `, Collector c){ if(tp is function) c.enterScope(current); collect(tp, c); if(tp is function) c.leaveScope(current); - calcDeps = [tp]; - functionScopes = c.getScopeInfo(functionScope()); - if(!isEmpty(functionScopes)){ - for(<_, scopeInfo> <- functionScopes){ - if(signatureInfo(Type returnType) := scopeInfo){ - calcDeps += returnType; - break; - } else { - throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: "); - } - } - } - c.calculate("typed variable pattern", current, calcDeps, AType(Solver s){ return s.getType(tp)[alabel=uname]; }); + calcDeps = addReturnTypeDependency(current, tp, c); + c.calculate("typed variable pattern", current, calcDeps, AType(Solver s){ return s.getType(tp)[alabel=uname]; }); - if(!isWildCard(uname)){ c.push(patternNames, ); orScopes = c.getScopeInfo(orScope()); @@ -120,7 +123,11 @@ void collect(current: (Pattern) ` `, Collector c){ } c.define(uname, formalOrPatternFormal(c), name, defType(tp)); } else { - c.fact(name, tp); + if(calcDeps == [tp]){ + c.fact(name, tp); + } else { + c.calculate("variable ", name, calcDeps, AType(Solver s) { return s.getType(tp); }); + } } } diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc index 71e91d02998..bb4384c6659 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc @@ -844,7 +844,7 @@ void collect(current:(TypeVar) `& `, Collector c){ void collect(current: (TypeVar) `& \<: `, Collector c){ pname = prettyPrintName(n); - + calcDeps = addReturnTypeDependency(current, tp, c); if( := defineOrReuseTypeParameters(c)){ if(c.isAlreadyDefined(pname, n)){ c.use(n, {typeVarId() }); @@ -856,20 +856,21 @@ void collect(current: (TypeVar) `& \<: `, Collector c){ c.fact(current, n); } else if( := useTypeParameters(c)){ c.use(n, {typeVarId() }); - c.calculate("xxx", current, [n], AType (Solver s) { return s.getType(n)[closed=closed]; }); + c.calculate("type parameter", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); //if(debugTP)println("Use at "); } else if( := useBoundedTypeParameters(c)){ if(!isEmpty(tpbounds[pname])){ bnds = toList(tpbounds[pname]); - c.calculate("type parameter with bound", n, bnds, + c.calculate("type parameter with bound", n, bnds + calcDeps, AType(Solver s){ new_bnd = (avalue() | aglb(it, s.getType(bnd)) | bnd <- bnds); return aparameter(prettyPrintName(n), s.getType(new_bnd), closed=true); }); } else { - c.calculate("type parameter with bound", n, [tp], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); + c.calculate("type parameter with bound", n, [tp, *calcDeps], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); } - c.fact(current, n); + //c.fact(current, n); + c.calculate("type parameter with bound", current, [tp, *calcDeps], AType(Solver s){ return s.getType(n); }); } collect(tp, c); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc new file mode 100644 index 00000000000..5ee4cd9816f --- /dev/null +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc @@ -0,0 +1,208 @@ +module lang::rascalcore::check::DependencyViewer + +import analysis::typepal::TModel; +import analysis::typepal::Collector; +import vis::Graphs; +import IO; +import util::IDEServices; +import ListRelation; +import Map; +import Relation; +import Set; + +// Management of node identities +alias NodeId = str; +int nodeCounter = 0; + +map[NodeId, value] id2node = (); +map[value, NodeId] node2id = (); + +map[NodeId,loc] node2src = (); +map[NodeId,str] node2label = (); +map[loc,NodeId] src2calc = (); + +void initNodes(){ + nodeCounter = 0; + id2node = (); + node2id = (); + node2src = (); + node2label = (); + src2calc = (); +} + +NodeId getNodeId(value v){ + assert Calculator _ := v || Requirement _ := v || loc _ := v: "Illegal "; + if(v notin node2id) { + node2id[v] = ""; + id2node[""] = v; + nodeCounter += 1; + } + return node2id[v]; +} + +NodeId getNodeIdViaCalculator(loc l){ + if(l in src2calc){ + return src2calc[l]; + } + return getNodeId(l); +} + +loc getNodeSource(NodeId id) { + if(id in node2src) return node2src[id]; + v = id2node[id]; + if(loc l := v) return l; + return |unknown:///|; +} + +str getNodeLabel(NodeId id) { + if(id in node2label) return node2label[id]; + v = id2node[id]; + if(loc l := v) return ": "; + return ": ???:"; +} + +str getText(loc l) { + try return readFile(l); + catch _: return "???"; +} + +lrel[NodeId,NodeId] srcDependsOn(NodeId src, list[loc] dependsOn) + = [ | d <- dependsOn]; + +lrel[NodeId,NodeId] srcDependsOn(NodeId l, NodeId r, list[loc] dependsOn) + = srcDependsOn(l, dependsOn) + srcDependsOn(r, dependsOn); + +lrel[NodeId,NodeId] calcEdges(c:calcType(loc src, AType atype)) { + id = getNodeId(c); + node2src[id] = src; + node2label[id] = ": "; + src2calc[src] = id; + return []; +} + +lrel[NodeId,NodeId] calcEdges(c:calcLoc(loc src, list[loc] dependsOn)){ + NodeId id = getNodeId(c); + node2src[id] = src; + node2label[id] = ": "; + src2calc[src] = id; + return srcDependsOn(id, dependsOn); +} + +lrel[NodeId,NodeId] calcEdges(c:calc(str cname, loc src, list[loc] dependsOn, AType(Solver s) getAType)){ + NodeId id = getNodeId(c); + node2src[id] = src; + node2label[id] = "C , : "; + src2calc[src] = id; + return srcDependsOn(id, dependsOn); +} + +lrel[NodeId,NodeId] calcEdges(c:calcLub(str cname, list[loc] srcs, list[loc] dependsOn, list[AType(Solver s)] getATypes)){ + NodeId id = getNodeId(c); + node2label[id] = "C , : /<}>"; + for(src <- srcs) src2calc[src] = id; + return srcDependsOn(id, dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:req(str rname, loc src, list[loc] dependsOn, void(Solver s) preds)){ + NodeId id = getNodeId(rq); + node2src[id] = src; + node2label[id] = "R : "; + return srcDependsOn(id, dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqEqual(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){ + NodeId id = getNodeId(rq); + node2label[id] = "R "; + return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqComparable(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){ + NodeId id = getNodeId(rq); + node2label[id] = "R "; + return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqSubtype(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){ + NodeId id = getNodeId(rq); + node2label[id] = "R "; + return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqUnify(str rname, value l, value r, list[loc] dependsOn, FailMessage fm)){ + NodeId id = getNodeId(rq); + node2label[id] = "R "; + return srcDependsOn(getNodeId(l), getNodeId(r), dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqError (loc src, list[loc] dependsOn, FailMessage fm)){ + NodeId id = getNodeId(rq); + node2src[id] = src; + node2label[id] = "R error: "; + return srcDependsOn(id, dependsOn); +} + +lrel[NodeId,NodeId] reqEdges(rq:reqErrors(loc src, list[loc] dependsOn, list[FailMessage] fms)){ + NodeId id = getNodeId(rq); + node2src[id] = src; + node2label[id] = "R errors: "; + return srcDependsOn(id, dependsOn); +} + +NodeId replaceByCalc(NodeId id){ + if(id in node2src){ + src = node2src[id]; + if(src in src2calc) return src2calc[src]; + } + return id; +} + +void viewDependencies(TModel tm){ + initNodes(); + for(Calculator c <- tm.calculators){ + NodeId id = getNodeId(c); + if(c has src){ + src2calc[c.src] = id; + } else if(c has srsc){ + for(src <- c.srcs){ + src2calc[src] = id; + } + } + } + + cedges = {*calcEdges(c) | Calculator c <- tm.calculators}; + redges = {*reqEdges(r) | Requirement r <- tm.requirements}; + edges = toList(cedges + redges); + println("edges: "); + for(NodeId id <- sort(domain(id2node))) { println(""); iprintln(id2node[id]); } + + list[str] nodeClassifier(NodeId id){ + res = []; + switch(id2node[id]){ + case Calculator _: res = ["calc"]; + case Requirement _: res = ["req"]; + case loc _: res = ["text"]; + } + return res; + } + + styles = [ + cytoStyleOf( + selector=\node(className("text")), + style=defaultNodeStyle()[shape=CytoNodeShape::rectangle()][\background-color="grey"]), + cytoStyleOf( + selector=\node(className("calc")), + style=defaultNodeStyle()[shape=CytoNodeShape::ellipse()][\background-color="green"]), + cytoStyleOf( + selector=\node(className("req")), + style=defaultNodeStyle()[shape=CytoNodeShape::diamond()][\background-color="blue"]) + ]; + cfg = cytoGraphConfig( + title="Graph: ", + nodeClassifier=nodeClassifier, + nodeLinker=getNodeSource, + nodeLabeler=getNodeLabel, + styles=styles, + \layout=defaultDagreLayout()); + + showInteractiveContent(graph(edges, cfg=cfg)); +} \ No newline at end of file diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc index 6e1f3894d83..a21fb21422a 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc @@ -47,6 +47,8 @@ import lang::rascalcore::compile::util::Names; import analysis::typepal::StringSimilarity; import analysis::typepal::LocationChecks; +import lang::rascalcore::check::DependencyViewer; + import IO; import List; import Map; @@ -403,6 +405,7 @@ rel[loc, PathRole,loc] enhancePathRelation(rel[MODID, PathRole, MODID] paths){ // Enhance TModel before running Solver by TModel rascalPreSolver(map[str,Tree] _namedTrees, TModel m){ + //viewDependencies(m); return m[paths = enhancePathRelation(m.paths)]; } diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc index c22e7c50b36..6165d3dbdb7 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc @@ -11,13 +11,16 @@ import lang::rascalcore::check::RascalConfig; import lang::rascalcore::check::Checker; import lang::rascal::\syntax::Rascal; -loc root = |memory://e0711529-477e-4a4c-b44b-44b00157728eXXX|; + +// this uuid matters +loc root = |memory://36a14c42-e4e6-41e0-a59a-ac11f637070c|; PathConfig pcfg = pathConfig( srcs = [root + "src"], bin = root + "bin", libs = [] ); + // this name matters str moduleName = "TestModule612d1"; @@ -25,7 +28,7 @@ loc writeModule() { loc moduleLoc = pcfg.srcs[0] + ".rsc"; // the spaces before &T seems to matter? writeFile(moduleLoc, - "module TestModule612d1\r\n \r\n &T \<: int f(&T \<: num _) = 1;" + "module TestModule612d1\r\n \n &T \<: int f(&T \<: num _) = 1;" ); return moduleLoc; } @@ -74,7 +77,7 @@ void findCollission(loc l) { } } - + void main() { remove(root, recursive = true); l = writeModule(); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc new file mode 100644 index 00000000000..26e51d5c534 --- /dev/null +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -0,0 +1,11 @@ +module lang::rascalcore::compile::Examples::Tst7 + + +&T <: int f(&T <: num _) = 1; + + +// int f(int n, int m) = 3; + + + + \ No newline at end of file From 263f25c120ca5162085e024adf7241a3f90cea6b Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:45:06 +0200 Subject: [PATCH 02/23] Fixed error in addReturnTypeDependency; added dependencies --- .../lang/rascalcore/check/CollectPattern.rsc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc index 471af5293a3..b2128fbf9c4 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc @@ -71,6 +71,8 @@ void collect(current: (Pattern) `{ <{Pattern ","}* elements0> }`, Collector c){ } c.push(patternContainer, "set"); collect(elements0, c); + c.calculate("set pattern", current, [e | e <- elements0], + AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); }); c.pop(patternContainer); } @@ -82,11 +84,13 @@ void collect(current: (Pattern) `[ <{Pattern ","}* elements0> ]`, Collector c){ } c.push(patternContainer, "list"); collect(elements0, c); + c.calculate("list pattern", current, [e | e <- elements0], + AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); }); c.pop(patternContainer); } list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){ - if(/TypeVar _ := tp){ + if(/TypeVar _ := current){ functionScopes = c.getScopeInfo(functionScope()); if(!isEmpty(functionScopes)){ for(<_, scopeInfo> <- functionScopes){ @@ -123,11 +127,7 @@ void collect(current: (Pattern) ` `, Collector c){ } c.define(uname, formalOrPatternFormal(c), name, defType(tp)); } else { - if(calcDeps == [tp]){ - c.fact(name, tp); - } else { - c.calculate("variable ", name, calcDeps, AType(Solver s) { return s.getType(tp); }); - } + c.calculate("variable ", name, calcDeps, AType(Solver s) { return s.getType(tp); }); } } From 727f88048eb2d7827311438481d4d79b1059bb47 Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:45:40 +0200 Subject: [PATCH 03/23] Added dependencies --- .../compiler/lang/rascalcore/check/CollectDeclaration.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index 493e2019f3d..36d477c8419 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -592,6 +592,7 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur c.define(tpname, typeVarId(), tp.name, defType(toList(typeParamBounds[tpname]), makeBoundDef(tp, typeParamBounds, closed=false))); c.fact(tp, tp.name); + //c.calculate("bounded type var", tp, [tp, returnType], makeTypeGetter(tp)); } } @@ -624,7 +625,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, [*formals,*kwFormals], + c.calculate("formals", parameters, [*formals,*kwFormals]/*+addReturnTypeDependency(parameters, parameters, c)*/, AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; From 8d82e834e914c81e776347c5c679e94133ee5704 Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:46:01 +0200 Subject: [PATCH 04/23] Added dependencies --- .../compiler/lang/rascalcore/check/CollectType.rsc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc index bb4384c6659..0ba44847759 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc @@ -853,24 +853,25 @@ void collect(current: (TypeVar) `& \<: `, Collector c){ c.define(pname, typeVarId(), n, defTypeCall([getLoc(tp)], AType(Solver s) {return aparameter(pname,s.getType(tp), closed=closed); })); //if(debugTP)println("Define at "); } - c.fact(current, n); + //c.fact(current, n); + c.calculate("type parameter, 1", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); } else if( := useTypeParameters(c)){ c.use(n, {typeVarId() }); - c.calculate("type parameter", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); + c.calculate("type parameter, 2", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); //if(debugTP)println("Use at "); } else if( := useBoundedTypeParameters(c)){ if(!isEmpty(tpbounds[pname])){ bnds = toList(tpbounds[pname]); - c.calculate("type parameter with bound", n, bnds + calcDeps, + c.calculate("type parameter with bound, 1", n, bnds + calcDeps, AType(Solver s){ new_bnd = (avalue() | aglb(it, s.getType(bnd)) | bnd <- bnds); return aparameter(prettyPrintName(n), s.getType(new_bnd), closed=true); }); } else { - c.calculate("type parameter with bound", n, [tp, *calcDeps], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); + c.calculate("type parameter with bound, 2", n, [tp, *calcDeps], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); } //c.fact(current, n); - c.calculate("type parameter with bound", current, [tp, *calcDeps], AType(Solver s){ return s.getType(n); }); + c.calculate("type parameter with bound, 3", current, [tp, *calcDeps], AType(Solver s){ return s.getType(n)[closed=true]; }); } collect(tp, c); From 0fecd2de2e29beff6ca279aca9e2c25ececc76eb Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:46:25 +0200 Subject: [PATCH 05/23] Commented out viewDependencies --- .../compiler/lang/rascalcore/check/DependencyViewer.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc index 5ee4cd9816f..f0992db2f10 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc @@ -202,7 +202,7 @@ void viewDependencies(TModel tm){ nodeLinker=getNodeSource, nodeLabeler=getNodeLabel, styles=styles, - \layout=defaultDagreLayout()); + \layout=defaultDagreLayout()[ranker=\tight-tree()]); showInteractiveContent(graph(edges, cfg=cfg)); } \ No newline at end of file From b2c5afde3fae0e1fb565c6c5c7132d3b97539b6d Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:47:05 +0200 Subject: [PATCH 06/23] Commented out viewDependencies --- .../rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc index a21fb21422a..6d9ad027161 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc @@ -405,7 +405,7 @@ rel[loc, PathRole,loc] enhancePathRelation(rel[MODID, PathRole, MODID] paths){ // Enhance TModel before running Solver by TModel rascalPreSolver(map[str,Tree] _namedTrees, TModel m){ - //viewDependencies(m); + // viewDependencies(m); return m[paths = enhancePathRelation(m.paths)]; } From 96b2ac0b6e2d8325062260fca8c07e77990e7e67 Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 15:47:37 +0200 Subject: [PATCH 07/23] Tests --- .../compiler/lang/rascalcore/compile/Examples/Tst7.rsc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index 26e51d5c534..b992640e899 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -1,5 +1,13 @@ module lang::rascalcore::compile::Examples::Tst7 + + +list[&T] tail([&T _, *&T t]) = t; + +&T top([&T t, *&T _]) = t; + +&T getFirstFrom([&T f, *&T _]) = f; +&T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); &T <: int f(&T <: num _) = 1; From bf591787fbd466892aff287f0ed7f773e3ac429a Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 20:58:53 +0200 Subject: [PATCH 08/23] Removed dependencies --- .../compiler/lang/rascalcore/check/CollectDeclaration.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index 36d477c8419..c363af6b6fc 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -625,7 +625,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, [*formals,*kwFormals]/*+addReturnTypeDependency(parameters, parameters, c)*/, + c.calculate("formals", parameters, [], AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; From 05703d5460deec075287825f58496f8ed9d3ac70 Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 23:15:16 +0200 Subject: [PATCH 09/23] Fixed type error --- .../lang/rascalcore/check/CollectPattern.rsc | 17 ----------------- .../lang/rascalcore/check/ScopeInfo.rsc | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc index b2128fbf9c4..e06a360ede0 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc @@ -88,23 +88,6 @@ void collect(current: (Pattern) `[ <{Pattern ","}* elements0> ]`, Collector c){ AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); }); c.pop(patternContainer); } - -list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){ - if(/TypeVar _ := current){ - functionScopes = c.getScopeInfo(functionScope()); - if(!isEmpty(functionScopes)){ - for(<_, scopeInfo> <- functionScopes){ - if(signatureInfo(Type returnType) := scopeInfo){ - return [tp, returnType]; - } else { - throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: "); - } - } - } - } - return [tp]; -} -// ---- typed variable pattern void collect(current: (Pattern) ` `, Collector c){ uname = unescape(""); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc index 01a64d4467b..4bf6f1658b6 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc @@ -158,5 +158,20 @@ void endUseBoundedTypeParameters(Collector c){ if(useBoundedTP(_) !:= handler) throw "beginUseBoundedTypeParameters/endUseBoundedTypeParameters not properly nested"; } - +list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){ + if(/TypeVar _ := current){ + functionScopes = c.getScopeInfo(functionScope()); + if(!isEmpty(functionScopes)){ + for(<_, scopeInfo> <- functionScopes){ + if(signatureInfo(Type returnType) := scopeInfo){ + return [tp, returnType]; + } else { + throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: "); + } + } + } + } + return [tp]; +} + data OrInfo = orInfo(set[str] vars); \ No newline at end of file From 7908765c9766b95803c7897abcb54a637a882647 Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 21 Apr 2026 23:44:45 +0200 Subject: [PATCH 10/23] Added missing import --- src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc index 4bf6f1658b6..f794c16e8fb 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc @@ -34,6 +34,7 @@ module lang::rascalcore::check::ScopeInfo import lang::rascalcore::check::BasicRascalConfig; import lang::rascalcore::check::NameUtils; import lang::rascal::\syntax::Rascal; +import lang::rascalcore::check::ATypeExceptions; public /*const*/ str patternContainer = "patternContainer"; public /*const*/ str patternNames = "patternNames"; From 2c6ca40c725ac91d93603a4d3310ec4f543f4fdd Mon Sep 17 00:00:00 2001 From: Davy Landman Date: Wed, 22 Apr 2026 16:48:03 +0200 Subject: [PATCH 11/23] Fixed test to the breaking case --- .../compiler/lang/rascalcore/compile/Examples/Tst5.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc index 6165d3dbdb7..38493926425 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst5.rsc @@ -28,7 +28,7 @@ loc writeModule() { loc moduleLoc = pcfg.srcs[0] + ".rsc"; // the spaces before &T seems to matter? writeFile(moduleLoc, - "module TestModule612d1\r\n \n &T \<: int f(&T \<: num _) = 1;" + "module TestModule612d1\n \n &T \<: int f(&T \<: num _) = 1;" ); return moduleLoc; } From 5a31df30ea5090b3d343228d604139d5458ef69d Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:41:26 +0200 Subject: [PATCH 12/23] Fixed handling of FunctionTypes in a signature --- .../lang/rascalcore/check/SyntaxGetters.rsc | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/SyntaxGetters.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/SyntaxGetters.rsc index 01504fe9163..d3dc91e44b8 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/SyntaxGetters.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/SyntaxGetters.rsc @@ -122,20 +122,25 @@ tuple[bool, TagString] getExpected(Tags tags){ return ; } - list[TypeVar] getTypeParams(Tree t){ - res = []; + set[TypeVar] res = {}; top-down-break visit(t){ case TypeVar tp : { res += tp; - if(tp is bounded) res += getTypeParams(tp.bound); + if(tp is bounded) res += toSet(getTypeParams(tp.bound)); } - //case FunctionType tp: ; - // // only type parameters in return type of a function type will be considered - // res += getTypeParams(tp.\type); + case StructuredType tp: { + res += {*getTypeParams(t.\type) | TypeArg t <- tp.arguments }; + } + case FunctionType tp:{ + // only type parameters in return type of a function type will be considered + typeParamsInReturn = toSet(getTypeParams(tp.\type)); + typeParamsInParameters = {*getTypeParams(t.\type) | TypeArg t <- tp.arguments }; + typeParameterNamesInParameters = { "" | TypeVar tp <- typeParamsInParameters }; + res += { tp | TypeVar tp <- typeParamsInReturn, "" notin typeParameterNamesInParameters }; + } } - - return res; + return toList(res); } set[Name] getTypeParamNames(Tree t){ From 8ecf960a34e4bd29eaf4af63c8aba5956eeac96d Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:43:42 +0200 Subject: [PATCH 13/23] Minor fixes --- .../compiler/lang/rascalcore/check/CollectDeclaration.rsc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index c363af6b6fc..4db527f9cb3 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -552,7 +552,7 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur // during collection. We cannot declare or use type parameters as they are encountered during collect // since their open/closed status has to be taken into account and that depends on the more global // context of the signature or function declaration in which they occur. That is why we explicitly create - // uses and defs nof type parameters. + // uses and defs for type parameters. typeParamsInParameters = [*getTypeParams(t) | t <- formals + kwFormals]; @@ -572,6 +572,7 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur c.use(tpbound.name, {typeVarId()}); } } + seenInReturn += ""; c.use(tp.name, {typeVarId()}); c.calculate("typevar in result type", tp, [tp.name], makeTypeGetter(tp,closed=true)); } @@ -592,7 +593,7 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur c.define(tpname, typeVarId(), tp.name, defType(toList(typeParamBounds[tpname]), makeBoundDef(tp, typeParamBounds, closed=false))); c.fact(tp, tp.name); - //c.calculate("bounded type var", tp, [tp, returnType], makeTypeGetter(tp)); + // c.calculate("bounded type var", tp, [tp], makeTypeGetter(tp)); } } @@ -625,7 +626,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, [], + c.calculate("formals", parameters, [] /*formals+kwFormals*/, AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; @@ -654,6 +655,7 @@ void(Solver) makeReturnRequirement(Tree returnExpr, AType returnAType) void returnRequirement(Tree returnExpr, AType declaredReturnType, Solver s){ returnExprType = s.getType(returnExpr); + // println("returnRequirement: , declared: , actual: "); FailMessage msg = p:/aparameter(_,_) := declaredReturnType ? error(returnExpr, "Returned type %t is not always a subtype of expected return type %t", returnExprType, declaredReturnType) : error(returnExpr, "Return type %t expected, found %t", declaredReturnType, returnExprType); From b4924da744d1aaf3fbc3701a18996007e0c74a12 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:48:17 +0200 Subject: [PATCH 14/23] Fixed incorrect type + cleanup --- .../compiler/lang/rascalcore/check/CollectPattern.rsc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc index e06a360ede0..686dddc05b6 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc @@ -72,7 +72,7 @@ void collect(current: (Pattern) `{ <{Pattern ","}* elements0> }`, Collector c){ c.push(patternContainer, "set"); collect(elements0, c); c.calculate("set pattern", current, [e | e <- elements0], - AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); }); + AType (Solver s){ return aset(lubList([s.getType(e) | e <- elements0])); }); c.pop(patternContainer); } @@ -94,8 +94,7 @@ void collect(current: (Pattern) ` `, Collector c){ if(tp is function) c.enterScope(current); collect(tp, c); if(tp is function) c.leaveScope(current); - calcDeps = addReturnTypeDependency(current, tp, c); - c.calculate("typed variable pattern", current, calcDeps, AType(Solver s){ return s.getType(tp)[alabel=uname]; }); + c.calculate("typed variable pattern", current, [tp], AType(Solver s){ return s.getType(tp)[alabel=uname]; }); if(!isWildCard(uname)){ c.push(patternNames, ); @@ -110,7 +109,7 @@ void collect(current: (Pattern) ` `, Collector c){ } c.define(uname, formalOrPatternFormal(c), name, defType(tp)); } else { - c.calculate("variable ", name, calcDeps, AType(Solver s) { return s.getType(tp); }); + c.calculate("variable ", name, [tp], AType(Solver s) { return s.getType(tp); }); } } From e2a904e786094044e799893ecd72a12570cc0ddd Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:49:45 +0200 Subject: [PATCH 15/23] Cleanup --- .../lang/rascalcore/check/CollectType.rsc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc index 0ba44847759..b15de673512 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc @@ -844,7 +844,6 @@ void collect(current:(TypeVar) `& `, Collector c){ void collect(current: (TypeVar) `& \<: `, Collector c){ pname = prettyPrintName(n); - calcDeps = addReturnTypeDependency(current, tp, c); if( := defineOrReuseTypeParameters(c)){ if(c.isAlreadyDefined(pname, n)){ c.use(n, {typeVarId() }); @@ -853,26 +852,26 @@ void collect(current: (TypeVar) `& \<: `, Collector c){ c.define(pname, typeVarId(), n, defTypeCall([getLoc(tp)], AType(Solver s) {return aparameter(pname,s.getType(tp), closed=closed); })); //if(debugTP)println("Define at "); } - //c.fact(current, n); - c.calculate("type parameter, 1", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); + c.fact(current, n); + //c.calculate("type parameter, 1", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); } else if( := useTypeParameters(c)){ c.use(n, {typeVarId() }); - c.calculate("type parameter, 2", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); + //c.fact(current, tp); + c.calculate("type parameter, 2", current, [n, tp], AType (Solver s) { return s.getType(n)[closed=closed]; }); //if(debugTP)println("Use at "); } else if( := useBoundedTypeParameters(c)){ if(!isEmpty(tpbounds[pname])){ bnds = toList(tpbounds[pname]); - c.calculate("type parameter with bound, 1", n, bnds + calcDeps, + c.calculate("type parameter with bound, 1", n, bnds + [tp], AType(Solver s){ new_bnd = (avalue() | aglb(it, s.getType(bnd)) | bnd <- bnds); return aparameter(prettyPrintName(n), s.getType(new_bnd), closed=true); }); } else { - c.calculate("type parameter with bound, 2", n, [tp, *calcDeps], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); + c.calculate("type parameter with bound, 2", n, [tp], AType(Solver s){ return aparameter(prettyPrintName(n), s.getType(tp), closed=true); }); } - //c.fact(current, n); - c.calculate("type parameter with bound, 3", current, [tp, *calcDeps], AType(Solver s){ return s.getType(n)[closed=true]; }); - } + c.fact(current, tp); + } collect(tp, c); } From e47dca33c0fce0d532cd7c5ca002f197e475ca26 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:50:22 +0200 Subject: [PATCH 16/23] Removed no longer used function --- .../compiler/lang/rascalcore/check/ScopeInfo.rsc | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc index f794c16e8fb..9fde073ce53 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc @@ -159,20 +159,5 @@ void endUseBoundedTypeParameters(Collector c){ if(useBoundedTP(_) !:= handler) throw "beginUseBoundedTypeParameters/endUseBoundedTypeParameters not properly nested"; } -list[Tree] addReturnTypeDependency(Tree current, Tree tp, Collector c){ - if(/TypeVar _ := current){ - functionScopes = c.getScopeInfo(functionScope()); - if(!isEmpty(functionScopes)){ - for(<_, scopeInfo> <- functionScopes){ - if(signatureInfo(Type returnType) := scopeInfo){ - return [tp, returnType]; - } else { - throw rascalCheckerInternalError(getLoc(current), "Inconsistent info from function scope: "); - } - } - } - } - return [tp]; -} data OrInfo = orInfo(set[str] vars); \ No newline at end of file From bccf55883bf00e80af9636e988134ca8ffe6c013 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:50:58 +0200 Subject: [PATCH 17/23] Added type info --- .../compiler/lang/rascalcore/check/DependencyViewer.rsc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc index f0992db2f10..1af404473c2 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/DependencyViewer.rsc @@ -72,8 +72,8 @@ lrel[NodeId,NodeId] srcDependsOn(NodeId src, list[loc] dependsOn) lrel[NodeId,NodeId] srcDependsOn(NodeId l, NodeId r, list[loc] dependsOn) = srcDependsOn(l, dependsOn) + srcDependsOn(r, dependsOn); -lrel[NodeId,NodeId] calcEdges(c:calcType(loc src, AType atype)) { - id = getNodeId(c); +lrel[NodeId,NodeId] calcEdges(Calculator c:calcType(loc src, AType atype)) { + NodeId id = getNodeId(c); node2src[id] = src; node2label[id] = ": "; src2calc[src] = id; From 35e21383e195d0bd31ebaf6185b1acd1abfd5b91 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 11:54:04 +0200 Subject: [PATCH 18/23] Test cases --- .../lang/rascalcore/compile/Examples/Tst7.rsc | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index b992640e899..86c29cc1b65 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -1,19 +1,51 @@ module lang::rascalcore::compile::Examples::Tst7 - -list[&T] tail([&T _, *&T t]) = t; +// import ParseTree; -&T top([&T t, *&T _]) = t; +// syntax Aas +// = nil: [a]* +// | a: [a][a]* +// | aas: [a][a][a]* +// ; +// &T <:Tree ambFilter(amb(set[&T <:Tree] alternatives)) { +// set[&T <:Tree] result = {a | Aas a <- alternatives, !(a is nil)}; +// if ({&T <: Tree oneTree} := result) { +// return oneTree; +// } +// return ParseTree::amb(result); +// } + +@javaClass{org.rascalmpl.library.Prelude} +java &U (type[&U] nonterminal, value input, loc origin) parsers(type[&T] grammar); + + + +list[&T] emptyList(type[&T] _) = []; // ok + +// &T f(&T x) { &T y = 1; return x;} // <==== error + +// void f(&T x) { &T y = 1; } // <==== error + +void g(&T x) { &T <: int y = 1; } // ok + +// &T get1(list[&T] _) = 1; // <==== error + +&T <: int get2(list[&T] _) = 1; // ok + +&T <: num sub(&T <:num x, &T<:num y) = x - y; // ok + +map[&K, &V] domainR1(map[&K, &V] M, set[&K] S) // ok + = (k : M[k] | &K k <- M, k in S); + +list[&T] tail([&T _, *&T t]) = t; // ok + +&T top([&T t, *&T _]) = t; // ok -&T getFirstFrom([&T f, *&T _]) = f; - -&T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); - -&T <: int f(&T <: num _) = 1; - - -// int f(int n, int m) = 3; - - - - \ No newline at end of file +&T getFirstFrom([&T f, *&T _]) = f; // ok + +&T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); //ok + +&T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok + +list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; + \ No newline at end of file From f36c5bc2ed3c9f3905a71475f1f21568ad47069d Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 30 Apr 2026 15:26:56 +0200 Subject: [PATCH 19/23] Special case for type parameter in nested function declaration. --- .../rascalcore/check/CollectDeclaration.rsc | 8 +++++++- .../lang/rascalcore/compile/Examples/Tst7.rsc | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index 4db527f9cb3..00a992532a4 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -598,9 +598,15 @@ private tuple[set[str], rel[str,Type]] computeBoundsAndDefineTypeParams(Signatur } // Due to their special treatment, missing type parameters are not detected by typepal but have to - // detected explicitly. + // be detected explicitly. missing = seenInReturn - seenInParams; + for(TypeVar x <- typeParamsInReturn){ + xname = ""; + if(xname in missing && c.isAlreadyDefined(xname, x)){ + missing -= xname; + } + } if(!isEmpty(missing)){ missing = {"&" | m <- missing }; c.report(error(signature, "Type parameter(s) %v in return type of function %q not bound by its formal parameters", missing, signature.name)); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index 86c29cc1b65..b8bf19d0937 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -47,5 +47,19 @@ list[&T] tail([&T _, *&T t]) = t; // ok &T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok -list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; - \ No newline at end of file +list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; // ok + +// Following ok +alias GatherResult[&T] = tuple[bool trueOnAllPaths, set[&T] results]; +data Graph[&T]; +data CFGNode; +public GatherResult[&T] gatherOnAllReachedPaths(Graph[CFGNode] g, CFGNode startNode, bool(CFGNode cn) pred, bool(CFGNode cn) stop, &T (CFGNode cn) gather, bool includeStartNode = false) { + GatherResult[&T] traverser(CFGNode currentNode) = traverser({currentNode}); + + GatherResult[&T] traverser(set[CFGNode] currentNodes) { + GatherResult[&T] res = < true, { } >; + return res; + } + + return traverser(startNode); +} \ No newline at end of file From 38c890fdba1913f023f36ebdda0dff6e13e79f77 Mon Sep 17 00:00:00 2001 From: paulklint Date: Sun, 3 May 2026 14:20:38 +0200 Subject: [PATCH 20/23] Return statement should depend on complete signature (not return type) In the case of type parameters with different bounds, we have to enforce that the complete signature is processed (including the adjustment of type parameter bounds) before any checking of the body is allowed. --- .../rascalcore/check/CollectDeclaration.rsc | 39 +++++--- .../rascalcore/check/CollectExpression.rsc | 4 +- .../lang/rascalcore/check/CollectPattern.rsc | 2 + .../lang/rascalcore/check/CollectType.rsc | 5 +- .../lang/rascalcore/check/ScopeInfo.rsc | 5 +- .../lang/rascalcore/compile/Examples/Tst7.rsc | 95 ++++++++++--------- 6 files changed, 86 insertions(+), 64 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index 00a992532a4..18597fb04ad 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -304,7 +304,7 @@ void collect(current: (FunctionDeclaration) ``, Collec c.enterLubScope(decl); collect(decl.tags, c); scope = c.getScope(); - c.setScopeInfo(scope, functionScope(), signatureInfo(signature.\type)); + c.setScopeInfo(scope, functionScope(), signatureInfo(signature)); = collectSignature(decl.signature, c); dt = defType([signature], AType(Solver s) { @@ -389,7 +389,7 @@ void collect(current: (FunctionDeclaration) ``, Collec // We do in this case not check that the type of the expression as a whole is compatible with the return type. // TODO: cover the case that we leave the expression via a return AND via the value of the expression as a whole } else { - c.require("check on return type ``", decl.expression, [decl.expression], makeReturnRequirement(decl.expression, signature.\type)); + c.require("check on return type ``", decl.expression, [decl.expression, signature], makeReturnRequirement(decl.expression, signature)); } collect(decl.expression, c); } @@ -439,6 +439,7 @@ str md5Contrib4signature(Signature signature){ tuple[set[str], rel[str,Type]] collectSignature(Signature signature, Collector c){ returnType = signature.\type; parameters = signature.parameters; + formals = getFormals(parameters); kwFormals = getKwFormals(parameters); beginUseTypeParameters(c, closed=true); @@ -474,6 +475,16 @@ tuple[set[str], rel[str,Type]] collectSignature(Signature signature, Collector c formalsList = [ updateBounds(fm, minB) | fm <- formalsList ]; kwFormalsList = [ kwf[fieldType = updateBounds(kwf.fieldType, minB)] | kwf <- computeKwFormals(kwFormals, s) ]; ft = afunc(rtU, formalsList, kwFormalsList); + if(!isEmpty(tpnames)){ + for(int i <- index(formalsList)){ + s.fact(formals[i], formalsList[i]); + // println("*** add fact: =\> "); + } + for(int i <- index(kwFormalsList)){ + s.fact( kwFormals[i], kwFormalsList[i].fieldType); + // println("*** add fact: =\> "); + } + } //ft = updateBounds(afunc(s.getType(returnType), formalsList, computeKwFormals(kwFormals, s)), minB); return ft; }); @@ -632,7 +643,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, [] /*formals+kwFormals*/, + c.calculate("formals", parameters, formals+kwFormals, AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; @@ -649,17 +660,19 @@ void collect(Parameters parameters, Collector c){ endPatternScope(c); } -void(Solver) makeReturnRequirement(Tree returnExpr, Type returnType) +void(Solver) makeReturnRequirement(Tree returnExpr, Signature signature) = void(Solver s){ - returnRequirement(returnExpr, s.getType(returnType), s); + returnRequirement(returnExpr, signature, s); }; -void(Solver) makeReturnRequirement(Tree returnExpr, AType returnAType) - = void(Solver s){ - returnRequirement(returnExpr, returnAType, s); - }; +// void(Solver) makeReturnRequirement(Tree returnExpr, AType returnAType, Parameters parameters) +// = void(Solver s){ +// returnRequirement(returnExpr, parameters, returnAType, s); +// }; -void returnRequirement(Tree returnExpr, AType declaredReturnType, Solver s){ +void returnRequirement(Tree returnExpr, Signature signature, Solver s){ + sigType = s.getType(signature); + declaredReturnType = sigType.ret; returnExprType = s.getType(returnExpr); // println("returnRequirement: , declared: , actual: "); FailMessage msg = p:/aparameter(_,_) := declaredReturnType @@ -699,9 +712,9 @@ void collect(current: (Statement) `return `, Collector c){ functionScopes = c.getScopeInfo(functionScope()); assert !isEmpty(functionScopes); for(<_, scopeInfo> <- functionScopes){ - if(signatureInfo(Type returnType) := scopeInfo){ - c.require("check return type", current, [statement, returnType], makeReturnRequirement(statement, returnType)); - c.fact(current, returnType); // Note that type of the return statement as a whole is the function's return type + if(signatureInfo(Signature signature) := scopeInfo){ + c.require("check return type", current, [statement, signature], makeReturnRequirement(statement, signature)); + c.fact(current, signature.\type); // Note that type of the return statement as a whole is the function's return type collect(statement, c); return; } else { diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index 7403133a2cb..e50dd18fc3e 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -230,7 +230,7 @@ void collectClosure(Expression current, Type returnType, Parameters parameters, parentScope = c.getScope(); c.enterLubScope(current); scope = c.getScope(); - c.setScopeInfo(scope, functionScope(), signatureInfo(returnType)); + c.setScopeInfo(scope, functionScope(), signatureInfo(returnType, parameters)); beginUseTypeParameters(c, closed=true); collect(returnType, c); // any type parameters in return type remain closed (closed=true); @@ -454,7 +454,7 @@ void collect(current: (Comprehension) `[ <{Expression ","}+ results> | <{Express try { c.fact(current, makeListType(lubList([ c.getType(r) | r <- res]))); } catch TypeUnavailable(): { - c.calculate("list comprehension results", current, res, + c.calculate("list comprehension results", current, gens + res, AType(Solver s){ return makeListType(lubList([ s.getType(r) | r <- res])); }); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc index 686dddc05b6..90cba30c98d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectPattern.rsc @@ -88,6 +88,8 @@ void collect(current: (Pattern) `[ <{Pattern ","}* elements0> ]`, Collector c){ AType (Solver s){ return alist(lubList([s.getType(e) | e <- elements0])); }); c.pop(patternContainer); } + +// ---- typed variable pattern void collect(current: (Pattern) ` `, Collector c){ uname = unescape(""); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc index b15de673512..540fcea638d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc @@ -856,8 +856,9 @@ void collect(current: (TypeVar) `& \<: `, Collector c){ //c.calculate("type parameter, 1", current, [n, *calcDeps], AType (Solver s) { return s.getType(n)[closed=closed]; }); } else if( := useTypeParameters(c)){ c.use(n, {typeVarId() }); - //c.fact(current, tp); - c.calculate("type parameter, 2", current, [n, tp], AType (Solver s) { return s.getType(n)[closed=closed]; }); + c.fact(current, tp); + // c.calculate("type parameter, 2", current, [n, tp], AType (Solver s) { + // return s.getType(n)[closed=closed]; }); //if(debugTP)println("Use at "); } else if( := useBoundedTypeParameters(c)){ if(!isEmpty(tpbounds[pname])){ diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc index 9fde073ce53..1de7355a659 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc @@ -34,7 +34,6 @@ module lang::rascalcore::check::ScopeInfo import lang::rascalcore::check::BasicRascalConfig; import lang::rascalcore::check::NameUtils; import lang::rascal::\syntax::Rascal; -import lang::rascalcore::check::ATypeExceptions; public /*const*/ str patternContainer = "patternContainer"; public /*const*/ str patternNames = "patternNames"; @@ -80,7 +79,7 @@ data VisitOrSwitchInfo = visitOrSwitchInfo(Expression expression, bool isVisit); // Information needed for checking return statement data SignatureInfo - = signatureInfo(Type returnType) + = signatureInfo(Signature signature) ; // Determine how type parameters (TypeVar in Rascal grammar) will be treated: @@ -159,5 +158,5 @@ void endUseBoundedTypeParameters(Collector c){ if(useBoundedTP(_) !:= handler) throw "beginUseBoundedTypeParameters/endUseBoundedTypeParameters not properly nested"; } - + data OrInfo = orInfo(set[str] vars); \ No newline at end of file diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index b8bf19d0937..40af5af9df4 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -1,65 +1,72 @@ module lang::rascalcore::compile::Examples::Tst7 -// import ParseTree; +// list[int] f(list[int] L) = [x | x <- L, x > 0]; + +// // int f(int n, int m, bool b = false) = 2; + +// // import ParseTree; -// syntax Aas -// = nil: [a]* -// | a: [a][a]* -// | aas: [a][a][a]* -// ; -// &T <:Tree ambFilter(amb(set[&T <:Tree] alternatives)) { -// set[&T <:Tree] result = {a | Aas a <- alternatives, !(a is nil)}; -// if ({&T <: Tree oneTree} := result) { -// return oneTree; -// } -// return ParseTree::amb(result); -// } +// // syntax Aas +// // = nil: [a]* +// // | a: [a][a]* +// // | aas: [a][a][a]* +// // ; +// // &T <:Tree ambFilter(amb(set[&T <:Tree] alternatives)) { +// // set[&T <:Tree] result = {a | Aas a <- alternatives, !(a is nil)}; +// // if ({&T <: Tree oneTree} := result) { +// // return oneTree; +// // } +// // return ParseTree::amb(result); +// // } -@javaClass{org.rascalmpl.library.Prelude} -java &U (type[&U] nonterminal, value input, loc origin) parsers(type[&T] grammar); +// @javaClass{org.rascalmpl.library.Prelude} +// java &U (type[&U] nonterminal, value input, loc origin) parsers(type[&T] grammar); -list[&T] emptyList(type[&T] _) = []; // ok +// list[&T] emptyList(type[&T] _) = []; // ok -// &T f(&T x) { &T y = 1; return x;} // <==== error +// // &T f(&T x) { &T y = 1; return x;} // <==== error -// void f(&T x) { &T y = 1; } // <==== error +// // void f(&T x) { &T y = 1; } // <==== error -void g(&T x) { &T <: int y = 1; } // ok +// void g(&T x) { &T <: int y = 1; } // ok -// &T get1(list[&T] _) = 1; // <==== error +// // &T get1(list[&T] _) = 1; // <==== error -&T <: int get2(list[&T] _) = 1; // ok +// &T <: int get2(list[&T] _) = 1; // ok -&T <: num sub(&T <:num x, &T<:num y) = x - y; // ok +// &T <: num sub(&T <:num x, &T<:num y) = x - y; // ok -map[&K, &V] domainR1(map[&K, &V] M, set[&K] S) // ok - = (k : M[k] | &K k <- M, k in S); +// map[&K, &V] domainR1(map[&K, &V] M, set[&K] S) // ok +// = (k : M[k] | &K k <- M, k in S); -list[&T] tail([&T _, *&T t]) = t; // ok +// list[&T] tail([&T _, *&T t]) = t; // ok -&T top([&T t, *&T _]) = t; // ok +// &T top([&T t, *&T _]) = t; // ok -&T getFirstFrom([&T f, *&T _]) = f; // ok +// &T getFirstFrom([&T f, *&T _]) = f; // ok -&T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); //ok - -&T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok - -list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; // ok +// &T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); //ok + +// &T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok + +&T <: int f(&T <: num x = 0) = 1; // discussie; ik (en checker) denken ok + +// list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; // ok -// Following ok -alias GatherResult[&T] = tuple[bool trueOnAllPaths, set[&T] results]; -data Graph[&T]; -data CFGNode; -public GatherResult[&T] gatherOnAllReachedPaths(Graph[CFGNode] g, CFGNode startNode, bool(CFGNode cn) pred, bool(CFGNode cn) stop, &T (CFGNode cn) gather, bool includeStartNode = false) { - GatherResult[&T] traverser(CFGNode currentNode) = traverser({currentNode}); +// // Following ok +// alias GatherResult[&T] = tuple[bool trueOnAllPaths, set[&T] results]; +// data Graph[&T]; +// data CFGNode; +// public GatherResult[&T] gatherOnAllReachedPaths(Graph[CFGNode] g, CFGNode startNode, bool(CFGNode cn) pred, bool(CFGNode cn) stop, &T (CFGNode cn) gather, bool includeStartNode = false) { +// GatherResult[&T] traverser(CFGNode currentNode) = traverser({currentNode}); - GatherResult[&T] traverser(set[CFGNode] currentNodes) { - GatherResult[&T] res = < true, { } >; - return res; - } +// GatherResult[&T] traverser(set[CFGNode] currentNodes) { +// GatherResult[&T] res = < true, { } >; +// return res; +// } - return traverser(startNode); -} \ No newline at end of file +// return traverser(startNode); +// } + From 0d5c7cc7b8d9ca9cadd2f99bfe7e65efea36154b Mon Sep 17 00:00:00 2001 From: paulklint Date: Sun, 3 May 2026 17:34:20 +0200 Subject: [PATCH 21/23] Fixed treatment of closures --- .../rascalcore/check/CollectDeclaration.rsc | 18 ++++++++++++++++++ .../rascalcore/check/CollectExpression.rsc | 3 ++- .../lang/rascalcore/check/ScopeInfo.rsc | 1 + .../lang/rascalcore/compile/Examples/Tst7.rsc | 5 ++++- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index 18597fb04ad..d011626efb7 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -665,6 +665,12 @@ void(Solver) makeReturnRequirement(Tree returnExpr, Signature signature) returnRequirement(returnExpr, signature, s); }; +void(Solver) makeReturnRequirement(Tree returnExpr, Type returnType) + = void(Solver s){ + returnRequirement(returnExpr, s.getType(returnType), s); + }; + + // void(Solver) makeReturnRequirement(Tree returnExpr, AType returnAType, Parameters parameters) // = void(Solver s){ // returnRequirement(returnExpr, parameters, returnAType, s); @@ -673,6 +679,12 @@ void(Solver) makeReturnRequirement(Tree returnExpr, Signature signature) void returnRequirement(Tree returnExpr, Signature signature, Solver s){ sigType = s.getType(signature); declaredReturnType = sigType.ret; + returnRequirement(returnExpr, s.getType(declaredReturnType), s); +} + +void returnRequirement(Tree returnExpr, AType declaredReturnType, Solver s){ + // sigType = s.getType(signature); + // declaredReturnType = sigType.ret; returnExprType = s.getType(returnExpr); // println("returnRequirement: , declared: , actual: "); FailMessage msg = p:/aparameter(_,_) := declaredReturnType @@ -712,6 +724,12 @@ void collect(current: (Statement) `return `, Collector c){ functionScopes = c.getScopeInfo(functionScope()); assert !isEmpty(functionScopes); for(<_, scopeInfo> <- functionScopes){ + if(signatureInfo(Type returnType, Parameters parameters) := scopeInfo){ + c.require("check return type", current, [statement, returnType, parameters], makeReturnRequirement(statement, returnType)); + c.fact(current, returnType); // Note that type of the return statement as a whole is the function's return type + collect(statement, c); + return; + } else if(signatureInfo(Signature signature) := scopeInfo){ c.require("check return type", current, [statement, signature], makeReturnRequirement(statement, signature)); c.fact(current, signature.\type); // Note that type of the return statement as a whole is the function's return type diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index e50dd18fc3e..7136855fa40 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -230,6 +230,7 @@ void collectClosure(Expression current, Type returnType, Parameters parameters, parentScope = c.getScope(); c.enterLubScope(current); scope = c.getScope(); + clos_name = closureName(current); c.setScopeInfo(scope, functionScope(), signatureInfo(returnType, parameters)); beginUseTypeParameters(c, closed=true); @@ -242,7 +243,7 @@ void collectClosure(Expression current, Type returnType, Parameters parameters, collect(stats, c); // TODO take parameter bounds into account! - clos_name = closureName(current); + bool returnsViaAll = returnsViaAllPath(stats, clos_name, c); formals = getFormals(parameters); kwFormals = getKwFormals(parameters); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc index 1de7355a659..1afa0d32139 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ScopeInfo.rsc @@ -80,6 +80,7 @@ data VisitOrSwitchInfo = visitOrSwitchInfo(Expression expression, bool isVisit); // Information needed for checking return statement data SignatureInfo = signatureInfo(Signature signature) + | signatureInfo(Type returnType, Parameters parameters) ; // Determine how type parameters (TypeVar in Rascal grammar) will be treated: diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index 40af5af9df4..8f415637765 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -1,6 +1,9 @@ module lang::rascalcore::compile::Examples::Tst7 // list[int] f(list[int] L) = [x | x <- L, x > 0]; + +bool isSorted(list[&T] l, bool (&T a, &T b) less = bool (&T a, &T b) { return a < b; }) + = !any([*_, &T a, &T b, *_] := l, less(b, a)); // // int f(int n, int m, bool b = false) = 2; @@ -49,7 +52,7 @@ module lang::rascalcore::compile::Examples::Tst7 // &T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); //ok -// &T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok +&T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok &T <: int f(&T <: num x = 0) = 1; // discussie; ik (en checker) denken ok From 579177f4a127c0e1f6813ba014ce2b5bf4561c26 Mon Sep 17 00:00:00 2001 From: paulklint Date: Sun, 3 May 2026 18:48:11 +0200 Subject: [PATCH 22/23] Removed dependencies --- .../compiler/lang/rascalcore/check/CollectDeclaration.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index d011626efb7..93461fc600a 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -643,7 +643,7 @@ void collect(Parameters parameters, Collector c){ } else { scope = c.getScope(); - c.calculate("formals", parameters, formals+kwFormals, + c.calculate("formals", parameters, [], //formals+kwFormals, AType(Solver s) { formalTypes = [ getPatternType(f, avalue(), scope, s) | f <- formals ]; int last = size(formalTypes) -1; From 070d3090c8ce0472d3cfed8e1fe753cafa607f60 Mon Sep 17 00:00:00 2001 From: paulklint Date: Sun, 3 May 2026 20:03:48 +0200 Subject: [PATCH 23/23] Fixed typo in message --- .../compiler/lang/rascalcore/check/AType.rsc | 2 ++ .../lang/rascalcore/check/RascalConfig.rsc | 2 +- .../lang/rascalcore/compile/Examples/Tst7.rsc | 18 ++++++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/AType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/AType.rsc index 8a7ce513151..c40bcd4605f 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/AType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/AType.rsc @@ -440,6 +440,8 @@ bool asubtype(a:anode(list[AType] l), AType b){ return true; case anode(list[AType] r): return l <= r; + case adt: aadt(str _, list[AType] _, _): + return true; case \start(t): return asubtype(a, t); case avalue(): diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc index 6d9ad027161..5feaa6e3793 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc @@ -441,7 +441,7 @@ void checkOverloading(map[str,Tree] namedTrees, Solver s){ r1 = visit(t1.ret) {case p:aparameter(_,_,closed=true) => p[closed=false] }; r2 = visit(t2.ret) {case p:aparameter(_,_,closed=true) => p[closed=false] }; if(!comparable(r1, r2)){ - causes = [ info("ther declaration with comparable arguments", d2.defined) ]; + causes = [ info("the declaration with comparable arguments", d2.defined) ]; msgs = [ error("Return type `` of function `` is not comparable with return type `` of other declaration with comparable arguments", d1.defined, causes=causes) ]; s.addMessages(msgs); } diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc index 8f415637765..5b1b4293d96 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Examples/Tst7.rsc @@ -1,9 +1,19 @@ module lang::rascalcore::compile::Examples::Tst7 + +@javaClass{org.rascalmpl.library.Prelude} +public java &T <: node setKeywordParameters(&T <: node x, map[str,value] keywordParameters); + +data Tree; + +Tree mergeRec(Tree t) { + return setKeywordParameters(t, ()); + } + // list[int] f(list[int] L) = [x | x <- L, x > 0]; -bool isSorted(list[&T] l, bool (&T a, &T b) less = bool (&T a, &T b) { return a < b; }) - = !any([*_, &T a, &T b, *_] := l, less(b, a)); +// bool isSorted(list[&T] l, bool (&T a, &T b) less = bool (&T a, &T b) { return a < b; }) +// = !any([*_, &T a, &T b, *_] := l, less(b, a)); // // int f(int n, int m, bool b = false) = 2; @@ -52,9 +62,9 @@ bool isSorted(list[&T] l, bool (&T a, &T b) less = bool (&T a, &T b) { return a // &T max([&T h, *&T t]) = (h | e > it ? e : it | e <- t); //ok -&T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok +// &T <: int f(&T <: num _) = 1; // discussie; ik (en checker) denken ok -&T <: int f(&T <: num x = 0) = 1; // discussie; ik (en checker) denken ok +// &T <: int f(&T <: num x = 0) = 1; // discussie; ik (en checker) denken ok // list[&U] mapper(list[&T] lst, &U (&T) fn) = [fn(elm) | &T elm <- lst]; // ok