I found some strange behavior that I believe to be a bug. I’m using Spoofax

  1. Build the attached project.
  2. Add a new example.tes file with the following code:
    var list : List<Int>;
    for (i : String in list) {}

    The TS code will error that String is not compatible with Int, as expected.

  3. Remove the : String such that this remains:

    var list : List<Int>;
    for (i in list) {}

    If you hover over i, you see that it is inferred to be Int, as expected.

  4. Change the type of the list to List<String>.

    var list : List<String>;
    for (i in list) {}

    If you now hover over i, it is still inferred to be Int while it should be String. This is not expected.

  5. Add the : String type back in the for-loop:

    var list : List<String>;
    for (i : String in list) {}

    If you hover over i, it is String, as expected.

  6. Remove : String again:

    var list : List<String>;
    for (i in list) {}

    If you hover over i, it is inferred to be String, as expected. But the code is exactly the same as after step 4 when it was incorrectly inferred to be Int.

It seems that NaBL sometimes depends on old data or old constructors when doing matching.

Here are the relevant parts:


context-free start-symbols
    Start                   = <<Statement*>>
    Sort.SimpleSort         = <<ID>>
    Sort.GenericSort        = [[ID] < [Sort+; separator=","] >]
    Exp.Var                 = <<ID>>
    Block.Block             = <{ <Statement*> }>
    Statement               = <<Block>>
    Statement.VarDecl       = <var <ID> : <Sort> ;>
    Statement.For           = <for ( <ID> : <Sort> in <Exp> ) <Block>>
    Statement.ForInferred   = <for ( <ID> in <Exp> ) <Block>>


binding rules

    For(v, ty, _, block):
        defines Variable v
        of type ty
        in block

    ForInferred(v, expr, block):
        defines Variable v
        of type ty
        in block
        where expr has type GenericSort(_, [ty])
    VarDecl(name, ty):
        defines Variable name
        of type ty
        in subsequent scope
        refers to Variable name
        scopes Variable


type rules

    Var(name) : ty
        where definition of name : ty
    For(v, ty, expr, _) :-
        where expr : expr-ty
        and (expr-ty => GenericSort(_, [e-ty])
        and ty == e-ty
            else error $[Type mismatch: expected [e-ty] got [ty]] on ty)
Submitted by D. Pelsmaeker on 13 June 2014 at 12:13
TestProject2.zip27 June 2014 at 10:53
TestProject.zip13 June 2014 at 12:13

On 13 June 2014 at 13:20 Gabriël Konat commented:

Could you also post your NaBL and TS rules for variable declarations and references?

On 13 June 2014 at 13:25 D. Pelsmaeker commented:

I’ve added all the remaining NaBL, TS and SDF3 rules to the post. That’s all there is in the project.

On 27 June 2014 at 10:55 D. Pelsmaeker commented:

I added a different test project that also shows the issue. In the test project’s example file, try changing the type of variable x and notice that variable y keeps its previous type until Reset and reanalyze.

Log in to post comments