Skip to content

[#1043] Break member access loop within with-statement

Nick Schrader requested to merge nschrader/vala:wip/issue/1043 into master

I suggest another solution than a1ea7697 for #1043 (closed) that not compromises lambdas.

The underlying problem is that in the following with-statement

with (a) {
   b ();
}

gets translated during symbol resolution into

with (a) {
   a.b ();
}

The with-statement is from thereon treated as a block.

This means that if both variable and member are called foo, the current compiler code translates recursively

with (foo) {
   foo ();
}

into

with (foo) {
   foo.foo ();
}

and then

with (foo) {
   foo.foo.foo ();
}

and so on, until the function stack explodes. To end the recursion, the member would eventually have to not be found in the with-statements's scope, so that the parent block's scope would be used for symbol resolution.

To break the loop, @ricotz made in a1ea7697 the symbol resolver change the scope to the parent block before doing this translation. However, in case of a lambda expression nested into the with-statement, this scope change leads to a confusion between the symbols of the lambda code and those of the surrounding code. The error message described in #1043 (closed) is the consequence.

Here, I suggest using a flag in the generated member access to indicate that the with-statement's scope shouldn't be used anymore, as it already has been for the said translation. This does not trouble any nested lambda statement. Of course, corresponding tests are provided and make test is passing.

This issue was really a hart nut to crack, sorry that it took me 2 months to fix. At least I know the member access module now like the back of my hand 😃.

Merge request reports