-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix JSON encoding of type values with recursive type #1705
Fix JSON encoding of type values with recursive type #1705
Conversation
Cadence Benchstat comparisonThis branch with compared with the base branch onflow:master commit ec9fb29 Results
|
Codecov Report
@@ Coverage Diff @@
## master #1705 +/- ##
=======================================
Coverage 76.63% 76.64%
=======================================
Files 292 292
Lines 61195 61207 +12
=======================================
+ Hits 46898 46910 +12
+ Misses 12684 12683 -1
- Partials 1613 1614 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
encoding/json/encode.go
Outdated
switch typ := typ.(type) { | ||
case cadence.CompositeType, cadence.InterfaceType: | ||
if _, ok := results[typ]; ok { | ||
return typ.ID() | ||
} | ||
results[typ] = struct{}{} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if these two checks are swapped, just to make sure any unhandled/ newly-added types are gracefully handled?
switch typ := typ.(type) { | |
case cadence.CompositeType, cadence.InterfaceType: | |
if _, ok := results[typ]; ok { | |
return typ.ID() | |
} | |
results[typ] = struct{}{} | |
} | |
if _, ok := results[typ]; ok { | |
switch typ := typ.(type) { | |
case cadence.CompositeType, cadence.InterfaceType: | |
return typ.ID() | |
default: | |
panic(fmt.Errorf("unsupported recursive type: %s", typ)) | |
} | |
} | |
results[typ] = struct{}{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good idea, it would be great to ensure all recursive types are supported!
This suggestions does not quite work as-is: It records all types as "seen", so e.g. even a primitive type like cadence.IntType
is erroneously considered an unsupported recursive type.
Tried to fix this by only recording the recursive types:
var supportedRecursiveType bool
switch typ.(type) {
case cadence.CompositeType, cadence.InterfaceType:
supportedRecursiveType = true
}
if _, ok := results[typ]; ok {
if !supportedRecursiveType {
panic(fmt.Errorf("failed to prepare type: unsupported recursive type: %T", typ))
}
return typ.ID()
}
if supportedRecursiveType {
results[typ] = struct{}{}
}
That then because we always check any type (results[typ]
), this panics for some types, e.g. functions, which are not pointers at the moment:
panic: runtime error: hash of unhashable type cadence.FunctionType
I guess we should keep the logic above and make all types hashable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, I wasn't thinking of the other types.
This looks good to me. Thanks for adding that!
Closes #1704
Description
Preparation of static types may run into a recursion. Track results and return the type ID in the recursive case.
master
branchFiles changed
in the Github PR explorer