Skip to content
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

Type Checking for attachment uses #2099

Merged
merged 50 commits into from
Dec 12, 2022

Conversation

dsainati1
Copy link
Contributor

@dsainati1 dsainati1 commented Oct 26, 2022

Part of #357 and #2061

This adds type checking for the uses of attachment types. In particular:

  • attachments can be added to values using attach A() to v, which requires its first expression to be an attachment constructor for which v is a valid composite base type
  • attachments can be removed from values using remove A from v, which requires its first expression to be an attachment name for which v is a valid composite base type
  • attachments can be accessed on resources and structs using v[A], which requires its indexing expression to be an attachment name for which v is a valid composite base type, and returns a value of type &A?
  • introduces two new types: AnyStructAttachment and AnyResourceAttachment, which are the supertypes of all struct and resource attachments respectively. These are subtypes of AnyStruct and AnyResource as well.
  • Because attachments are not first-class values, they can only be used in annotations when inside of a reference type

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work
  • Code follows the standards mentioned here
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

@dsainati1 dsainati1 requested review from dreamsmasher and a team October 26, 2022 19:02
@dsainati1 dsainati1 self-assigned this Oct 26, 2022
runtime/sema/type_tags.go Outdated Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
@SupunS SupunS mentioned this pull request Oct 27, 2022
6 tasks
runtime/ast/expression_extractor.go Show resolved Hide resolved
runtime/sema/check_assignment.go Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Reviewed everything except sema/type.go, need to review the new subtyping rules in detail.

runtime/sema/check_attach_expression.go Outdated Show resolved Hide resolved
runtime/sema/check_attach_expression.go Outdated Show resolved Hide resolved
runtime/sema/check_attach_expression.go Outdated Show resolved Hide resolved
runtime/sema/check_attach_expression.go Show resolved Hide resolved
runtime/sema/check_composite_declaration.go Show resolved Hide resolved
runtime/sema/errors.go Outdated Show resolved Hide resolved
runtime/sema/errors.go Outdated Show resolved Hide resolved
runtime/sema/check_attach_expression.go Outdated Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
Base automatically changed from sainati/attachments-checking to feature/attachments December 1, 2022 19:31
@codecov
Copy link

codecov bot commented Dec 1, 2022

Codecov Report

Merging #2099 (d40e7e3) into feature/attachments (73d73b0) will increase coverage by 0.09%.
The diff coverage is 86.17%.

@@                   Coverage Diff                   @@
##           feature/attachments    #2099      +/-   ##
=======================================================
+ Coverage                77.65%   77.75%   +0.09%     
=======================================================
  Files                      310      312       +2     
  Lines                    65899    66251     +352     
=======================================================
+ Hits                     51176    51513     +337     
- Misses                   12936    12948      +12     
- Partials                  1787     1790       +3     
Flag Coverage Δ
unittests 77.75% <86.17%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
encoding/json/encode.go 94.52% <ø> (ø)
runtime/ast/attachment.go 87.02% <ø> (+2.16%) ⬆️
runtime/ast/expression_extractor.go 46.19% <0.00%> (-2.54%) ⬇️
runtime/compiler/compiler.go 54.19% <0.00%> (-1.17%) ⬇️
runtime/interpreter/interpreter_expression.go 86.26% <0.00%> (-0.29%) ⬇️
runtime/interpreter/interpreter_statement.go 91.32% <0.00%> (-0.67%) ⬇️
runtime/sema/type.go 89.89% <86.51%> (-0.05%) ⬇️
runtime/common/compositekind.go 90.00% <88.88%> (-0.10%) ⬇️
runtime/sema/check_attach_expression.go 94.91% <94.91%> (ø)
encoding/json/decode.go 88.42% <100.00%> (+0.25%) ⬆️
... and 20 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@github-actions
Copy link

github-actions bot commented Dec 1, 2022

Cadence Benchstat comparison

This branch with compared with the base branch onflow:feature/attachments commit 8747c50
The command for i in {1..N}; do go test ./... -run=XXX -bench=. -benchmem -shuffle=on; done was used.
Bench tests were run a total of 7 times on each branch.

Collapsed results for better readability

old.txtnew.txt
time/opdelta
CheckContractInterfaceFungibleTokenConformance-2116µs ± 0%118µs ± 2%+1.57%(p=0.001 n=6+7)
ContractInterfaceFungibleToken-238.5µs ± 1%38.7µs ± 1%~(p=0.589 n=6+6)
InterpretRecursionFib-22.36ms ± 0%2.38ms ± 2%~(p=0.432 n=5+7)
NewInterpreter/new_interpreter-21.11µs ± 1%1.12µs ± 1%~(p=0.102 n=6+6)
NewInterpreter/new_sub-interpreter-2616ns ± 8%606ns ± 1%~(p=0.945 n=7+6)
ParseArray-28.07ms ± 3%8.24ms ± 3%~(p=0.101 n=6+7)
ParseDeploy/byte_array-212.4ms ± 6%12.4ms ± 6%~(p=1.000 n=7+7)
ParseDeploy/decode_hex-21.23ms ± 1%1.24ms ± 1%~(p=0.051 n=7+6)
ParseFungibleToken/With_memory_metering-2190µs ± 1%189µs ± 1%~(p=0.628 n=7+6)
ParseFungibleToken/Without_memory_metering-2150µs ± 2%149µs ± 2%~(p=0.366 n=6+7)
ParseInfix-26.97µs ± 2%6.93µs ± 1%~(p=0.318 n=7+7)
QualifiedIdentifierCreation/One_level-22.34ns ± 0%2.35ns ± 0%~(p=0.340 n=7+6)
QualifiedIdentifierCreation/Three_levels-2135ns ± 1%137ns ± 1%+1.69%(p=0.005 n=6+7)
RuntimeFungibleTokenTransfer-2580µs ±26%651µs ±20%~(p=0.165 n=7+7)
RuntimeResourceDictionaryValues-25.27ms ± 3%5.35ms ± 2%~(p=0.128 n=7+7)
RuntimeScriptNoop-213.2µs ± 1%18.3µs ±34%~(p=0.101 n=6+7)
SuperTypeInference/arrays-2309ns ± 1%317ns ± 1%+2.45%(p=0.001 n=7+6)
SuperTypeInference/composites-2133ns ± 0%133ns ± 0%+0.31%(p=0.001 n=7+6)
SuperTypeInference/integers-292.3ns ± 0%94.2ns ± 0%+2.11%(p=0.001 n=7+7)
ValueIsSubtypeOfSemaType-292.7ns ± 3%91.6ns ± 3%~(p=0.218 n=7+6)
 
alloc/opdelta
CheckContractInterfaceFungibleTokenConformance-248.9kB ± 0%48.9kB ± 0%~(p=0.462 n=7+7)
ContractInterfaceFungibleToken-223.0kB ± 0%23.0kB ± 0%~(all equal)
InterpretRecursionFib-21.00MB ± 0%1.00MB ± 0%~(p=1.000 n=7+7)
NewInterpreter/new_interpreter-2768B ± 0%768B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-2200B ± 0%200B ± 0%~(all equal)
ParseArray-22.74MB ± 3%2.75MB ± 4%~(p=0.589 n=6+6)
ParseDeploy/byte_array-24.16MB ± 3%4.14MB ± 3%~(p=1.000 n=7+7)
ParseDeploy/decode_hex-2214kB ± 0%214kB ± 0%~(p=0.245 n=7+7)
ParseFungibleToken/With_memory_metering-229.4kB ± 0%29.4kB ± 0%~(all equal)
ParseFungibleToken/Without_memory_metering-229.4kB ± 0%29.4kB ± 0%~(p=0.279 n=7+6)
ParseInfix-21.91kB ± 0%1.92kB ± 0%+0.17%(p=0.005 n=6+7)
QualifiedIdentifierCreation/One_level-20.00B 0.00B ~(all equal)
QualifiedIdentifierCreation/Three_levels-264.0B ± 0%64.0B ± 0%~(all equal)
RuntimeFungibleTokenTransfer-2101kB ± 1%101kB ± 1%~(p=0.596 n=7+7)
RuntimeResourceDictionaryValues-22.29MB ± 0%2.29MB ± 0%~(p=0.639 n=7+5)
RuntimeScriptNoop-26.82kB ± 0%6.85kB ± 0%+0.37%(p=0.038 n=6+7)
SuperTypeInference/arrays-296.0B ± 0%96.0B ± 0%~(all equal)
SuperTypeInference/composites-20.00B 0.00B ~(all equal)
SuperTypeInference/integers-20.00B 0.00B ~(all equal)
ValueIsSubtypeOfSemaType-248.0B ± 0%48.0B ± 0%~(all equal)
 
allocs/opdelta
CheckContractInterfaceFungibleTokenConformance-2797 ± 0%797 ± 0%~(all equal)
ContractInterfaceFungibleToken-2363 ± 0%363 ± 0%~(all equal)
InterpretRecursionFib-218.9k ± 0%18.9k ± 0%~(all equal)
NewInterpreter/new_interpreter-213.0 ± 0%13.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-24.00 ± 0%4.00 ± 0%~(all equal)
ParseArray-259.6k ± 0%59.6k ± 0%~(p=1.000 n=7+7)
ParseDeploy/byte_array-289.4k ± 0%89.4k ± 0%~(p=1.000 n=7+7)
ParseDeploy/decode_hex-264.0 ± 0%64.0 ± 0%~(all equal)
ParseFungibleToken/With_memory_metering-2779 ± 0%779 ± 0%~(all equal)
ParseFungibleToken/Without_memory_metering-2779 ± 0%779 ± 0%~(all equal)
ParseInfix-248.0 ± 0%48.0 ± 0%~(all equal)
QualifiedIdentifierCreation/One_level-20.00 0.00 ~(all equal)
QualifiedIdentifierCreation/Three_levels-22.00 ± 0%2.00 ± 0%~(all equal)
RuntimeFungibleTokenTransfer-21.97k ± 0%1.97k ± 0%~(all equal)
RuntimeResourceDictionaryValues-236.9k ± 0%36.9k ± 0%~(p=0.050 n=7+6)
RuntimeScriptNoop-298.0 ± 0%98.0 ± 0%~(all equal)
SuperTypeInference/arrays-23.00 ± 0%3.00 ± 0%~(all equal)
SuperTypeInference/composites-20.00 0.00 ~(all equal)
SuperTypeInference/integers-20.00 0.00 ~(all equal)
ValueIsSubtypeOfSemaType-21.00 ± 0%1.00 ± 0%~(all equal)
 

@turbolent
Copy link
Member

@dsainati1 Points 5 and 6 in the description are not part of the PR anymore, right?

@dsainati1
Copy link
Contributor Author

Ah yea good point

Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, really great work on this PR! 👏

I reviewed the remaining code, especially sema/type.go and IsSubType in particular. If you wan we can maybe have another (short) review session to discuss the remaining points.

runtime/sema/check_attach_expression.go Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
Comment on lines 5511 to 5520
case *InterfaceType:
switch typedInnerSubType := typedSubType.Type.(type) {
case *CompositeType:
return typedInnerSubType.ExplicitInterfaceConformanceSet().Contains(typedInnerSuperType)
// An interface type is a supertype of a restricted type if the restricted set contains
// that explicit interface type. Once interfaces can conform to interfaces, this should instead
// check that at least one value in the restriction set is a subtype of the interface supertype
case *RestrictedType:
return typedInnerSubType.RestrictionSet().Contains(typedInnerSuperType)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation ignores the restricted type (T in &T{Us}), does it need to be checked too?

Comment on lines 5511 to 5520
case *InterfaceType:
switch typedInnerSubType := typedSubType.Type.(type) {
case *CompositeType:
return typedInnerSubType.ExplicitInterfaceConformanceSet().Contains(typedInnerSuperType)
// An interface type is a supertype of a restricted type if the restricted set contains
// that explicit interface type. Once interfaces can conform to interfaces, this should instead
// check that at least one value in the restriction set is a subtype of the interface supertype
case *RestrictedType:
return typedInnerSubType.RestrictionSet().Contains(typedInnerSuperType)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this special rule to the subtype checking, maybe this can be a separate function that can be used where needed? (Where is it needed?)

runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
Comment on lines +5633 to +5634
case *RestrictedType:
return typedSubType.RestrictionSet().Contains(typedSuperType)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: Maybe this can be a separate function that is only used for this purpose.

The IsSubType function is already very complex, and so far assumes / could rely on the fact that interfaces only appear in restricted types. I'm worried the rules / this function becomes incomplete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dsainati1 and others added 4 commits December 7, 2022 10:11
Co-authored-by: Bastian Müller <bastian@axiomzen.co>
…low/cadence into sainati/attachments-check-add-remove
@dsainati1 dsainati1 changed the base branch from feature/attachments to attachments-master-merge December 9, 2022 15:10
Base automatically changed from attachments-master-merge to feature/attachments December 9, 2022 18:17
Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! 👏

Just some more suggestions for improving the comments even further, but finally ready to go! 🎉
Sorry this too so long, but this PR touches a lot of pieces

runtime/sema/check_attach_expression.go Outdated Show resolved Hide resolved
runtime/sema/check_composite_declaration.go Outdated Show resolved Hide resolved
runtime/sema/check_invocation_expression.go Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
runtime/sema/type.go Outdated Show resolved Hide resolved
runtime/sema/type.go Show resolved Hide resolved
@dsainati1 dsainati1 merged commit 3abda1a into feature/attachments Dec 12, 2022
@dsainati1 dsainati1 deleted the sainati/attachments-check-add-remove branch December 12, 2022 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants