Subsequent scope not possible without shadowing (1)
It is not possible to have definitions in subsequent scope without allowing shadowing. E.g.:
Int x; Int x;
The 2nd x shadows the first x and does not give a duplicate definition error. Incorrect in Java, C#, GM, Scala, … . Corresponding NaBL rule:
Submitted by Vlad Vergu on 2 July 2013 at 19:57Decl(t, var): defines Variable var of type t in subsequent scope
Issue Log
IMO, this is not really an error and not related to subsequent scopes. You have the same with regular scopes. In Java,
int x; { int x; }
is also not allowed, because variable hiding is in general forbidden. What we need is a mechanism to specify error messages
VarDec(ty, v): defines Variable v of type ty in subsequent scope error $[hiding variable [v'] in same or outer scope] where v hides Variable v'
The problem is that with
int x; int x; x;
the second
x
shadows the firstx
, because in subsequent scope generates new scopes after each variable definition. The result of the lookup ofx
is then one definition instead of two, which is generally wrong since most languages (Java, C#, C, etc) do not allow shadowing within the same scope.You still want to disallow use before definition, but in this case the second
x
should not hide the firstx
so in subseqent scope cannot be used.
I don’t understand your explanation. Why would you like to get two definitions and why is it wrong to get just one? In Java it is already wrong to have the second definition, and we should report an error on this. But it is the same as with regular scopes, like in the block. There, you also need an error. Reconsider my above example. Resolving the
x
inside the block will also give you just one definition. The key is that hiding is forbidden, and we should give an error there. The same holds for variables in subsequent scopes. If hiding is allowed, everything is fine. If it is forbidden, you need to specify an error check.You can currently implement manual error messages for hiding following this pattern:
type-of(|ctx): VarDecl(_, x) -> <fail> where uri := <nabl-uri> x ; uri' := <...> uri // create uri in parent scope ; task := <...> uri' // create task for lookup x in outer scopes ; <task-create-error-on-success(|ctx, task, "hiding!")> x
This is the actual type-of rule that does it:
type-of(|ctx): Decl(_, [var], _) -> <fail> where uri := <nabl-uri> var ; uri' := <nabl-uri-parent; nabl-uri-parent> uri ; task* := <nabl-use-subtasks(id, fail|ctx, <nabl-uri-namespace> uri, <nabl-uri-name> uri, [], All())> uri' ; task := <new-task(|ctx)> Choice(task*) ; <task-create-error-on-success(|ctx, task, "hiding!")> var
You’d like to get two definitions for a duplicate definitions error. I guess you can also just use a hiding error instead of duplicate definition.
Feel free to close this issue if you think we’ve reached an acceptable solution from NaBL point of view.
Log in to post comments