rascal icon indicating copy to clipboard operation
rascal copied to clipboard

Incomplete type inference for variable assigned in a for loop?

Open jurgenvinju opened this issue 2 years ago • 0 comments

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 produce void here
  • weights = () on line 3 indeed initializes to map[void,void]
  • but weights += (p : p in recProds ? recWeight : notRecWeight | p <- prods); "lubs" this immediately to map[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.

jurgenvinju avatar Aug 24 '23 12:08 jurgenvinju