[Bug fix] Module level user-defined types which are based on constants, have incorrect types #35745
Replies: 6 comments 4 replies
-
In my opinion approach number 2 is the ideal solution. I think this will take some considerable effort. |
Beta Was this translation helpful? Give feedback.
-
We can also keep unresolved dependent types like |
Beta Was this translation helpful? Give feedback.
-
Identified possible scenarios that we have to consider during this fix const int A = 2;
type B A; const int A = 2;
A a = 2; const int A = 1 + B;
const int B = 2; const map<map<boolean>> A = { "key5": B};
const map<boolean> B = { "key1": true}; type X int;
const X A = 1; type Foo record {
string s;
int i;
};
const Foo X = {s: "a", i: 2}; type Foo record {
string s;
int i;
};
type Foo2 record {
X s;
};
const Foo X = {s: "a", i: 2}; const string A = "b" + "c";
type X A;
const X B = "bc"; |
Beta Was this translation helpful? Give feedback.
-
Related WIP PR #35927 |
Beta Was this translation helpful? Give feedback.
-
After having a few offline discussions, we have identified the following options to move the
|
Beta Was this translation helpful? Give feedback.
-
After having few offline discussions with @hasithaa, we have decided to change the type resolving algorithm similar to nballerina approach (depth first approach). Created a new issue to track this effort (#36538). |
Beta Was this translation helpful? Give feedback.
-
Related issue #33890,
Reason: In the current implementation, compiler resolves the constants at
ConstantValueResolver
in semantic analyzer phase. But type nodes of module level variables are already resolved before resolving the constants. Therefore, even compiler updates the constants with correct types in later stage, it will not fix the module level usages (as a type) of the constants.After having offline discussions with @gimantha, @MaryamZi, @KRVPerera and @rdhananjaya, we came up with following possible ways to fix this issue.
After resolving the constants, we can search and update the module level usages which depend on constants.
cons - I have already tried this method. It is getting complicated for complex types like
record
.Change the current working flow by moving the
ConstantValueResolver
intoSymbolEnter
.cons - there can be dependencies which are not available at
SymbolEnter
Use a middle man that we can update when we have all the information.
We can take 2 approaches to this:
Use this middleman everywhere instead of the original type/symbol.
Register lambdas that know how to change all occurrences of type/symbol represented by this and invoke all of those lambdas to change all places.
We might have to have 2 classes, one for the type and one for the symbol.
This is just a holder class that holds the actual type, whenever we want to change the type, we can change the inner type field.
The problem with this approach is that we need to make sure never to store the inner type value, instead whenever we need to store the type we store the holder type. Failing to adhere to this will cause hald to find bugs.
We store list of lambdas that know how to change all occurrences of a type.
For example when ever we store a type somewhere we need to register a lambda function that upon invocation will set a new type in the same location.
When we want to store a new value (replace the type) we can just invoke those lambdas with the new type and it will be updated in all the places.
Highly appreciate your input on this discussion.
Beta Was this translation helpful? Give feedback.
All reactions