[Bug]: Annotation values with mapping values panic at runtime for const annotations
MaryamZi opened this issue · comments
Description
$title.
Steps to Reproduce
public type AnnotationRecord record {|
string summary?;
Examples examples?;
|};
public type Examples record {|
map<ExampleItem> response;
|};
public type ExampleItem record {
map<string> headers?;
};
const annotation AnnotationRecord annot on type;
@annot {
examples: {
response: {}
}
}
type Employee record {|
int id;
string name;
|};
error: {ballerina/lang.map}InherentTypeViolation {"message":"invalid value for record field 'examples': expected value of type 'record {| readonly record {| |} & readonly response; |} & readonly', found 'Examples'"}
at x:$annot_func$_0(demo.bal:16)
The value seems to be created as a mutable value.
Works when Examples
is updated to be an immutable record (since the value is then created as an immutable value due to Examples
' type).
public type Examples readonly & record {|
map<ExampleItem> response;
|};
Affected Version(s)
2201.9.1 and older versions
OS, DB, other environment details and versions
No response
Related area
-> Compilation
Related issue(s) (optional)
No response
Suggested label(s) (optional)
No response
Suggested assignee(s) (optional)
No response
When creating the annotation value, we make it immutable by invoking cloneReadonly
. The problem occurs when populating the initial values of the record.
In the above example,
public type AnnotationRecord record {|
string summary?;
Examples examples?;
|};
When creating the AnnotationRecord
value, we use the type of the field as Examples
, and do a istypecheck
with the type of the field. That is immutable.
We can fix this by making the field read-only as well.
public type AnnotationRecord record {|
string summary?;
Examples & readonly examples?;
|};
public type Examples record {|
map<ExampleItem> response;
|};
public type ExampleItem record {
map<string> headers?;
};
const annotation AnnotationRecord annot on type;
@annot {
examples: {
response: {}
}
}
type Employee record {|
int id;
string name;
|};
The problem occurs, we call cloneReadonly
on {examples: {response: {}}}
and set the type correctly. However, the type of {response: {}}
is set to Examples
, and we do not create cloneReadonly
for this.
As a workaround for this issue, we can define the Examples
type as read-only.
Fixed with #42966
This issue is NOT closed with a proper Reason/ label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.
- Reason/EngineeringMistake - The issue occurred due to a mistake made in the past.
- Reason/Regression - The issue has introduced a regression.
- Reason/MultipleComponentInteraction - Issue occured due to interactions in multiple components.
- Reason/Complex - Issue occurred due to complex scenario.
- Reason/Invalid - Issue is invalid.
- Reason/Other - None of the above cases.