rascal
rascal copied to clipboard
Incomplete type inference for variable assigned in a for loop?
Describe the bug
[ERROR] Termination.rsc:053:37: Replacement expression of field update` should not have type `void`
in:
Grammar terminationWeights(Grammar g) {
deps = dependencies(g.rules);
weights = ();
recProds = {p | /p:prod(s,[*_,t,*_],_) := g, <delabel(t), delabel(s)> in deps};
for (nt <- g.rules) {
prods = {p | /p:prod(_,_,_) := g.rules[nt]};
count = size(prods);
recCount = size(prods & recProds);
notRecCount = size(prods - recProds);
// at least 50% of the weight should go to non-recursive rules if they exist
notRecWeight = notRecCount != 0 ? (count * 10) / (2 * notRecCount) : 0;
recWeight = recCount != 0 ? (count * 10) / (2 * recCount) : 0;
weights += (p : p in recProds ? recWeight : notRecWeight | p <- prods);
}
return visit (g) {
case p:prod(_, _, _) => p[weight=weights[p]] // THIS ERROR
}
}
weights[p]is assumed to producevoidhereweights = ()on line 3 indeed initializes tomap[void,void]- but
weights += (p : p in recProds ? recWeight : notRecWeight | p <- prods);"lubs" this immediately tomap[Production,int]
It seems like the inferred type for weights is skipping the additive assignment to weights?
Have to reduce this still to a simpler example, but for now I'm adding map[Production,int] weights = () to avoid the problem.