There's currently no explicit lexical_scope set on the expression of a StorageLayoutSpecifier, which means it's using the one from the closest CST node, in this case the ContractDefinition itself.
This works but is not correct semantically, as we could bind to definitions inside the contract. And I realize now that this is also wrong (for the same reason) for InheritanceSpecifier, to allow code like:
uint constant B = 42;
contract Base {
constructor(uint) {}
}
contract Foo is Base(B) {}
We should use @contract.parent_scope instead, ie. something like:
@contract [ContractDefinition [ContractSpecifiers
[ContractSpecifier @specifier (
[InheritanceSpecifier]
| [StorageLayoutSpecifier]
)]
]] {
let @specifier.lexical_scope = @contract.parent_scope
}
Originally posted by @ggiraldez in #1288 (comment)
There's currently no explicit
lexical_scopeset on the expression of aStorageLayoutSpecifier, which means it's using the one from the closest CST node, in this case theContractDefinitionitself.This works but is not correct semantically, as we could bind to definitions inside the contract. And I realize now that this is also wrong (for the same reason) for
InheritanceSpecifier, to allow code like:We should use
@contract.parent_scopeinstead, ie. something like:Originally posted by @ggiraldez in #1288 (comment)