-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #53 from onflow/sainati/upgrade-guide
Upgrade guide for types
- Loading branch information
Showing
2 changed files
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
--- | ||
title: Cadence Type Annotations 1.0 Migration Guide | ||
sidebar_position: 5 | ||
sidebar_label: Cadence Type Annotations 1.0 Guide | ||
--- | ||
|
||
# Type Annotations in Cadence 1.0 | ||
|
||
In addition to updating your contracts in reaction to the Core Contract changes in Cadence 1.0, | ||
certain language changes in Cadence 1.0 will also require changes to type annotations in your contracts, | ||
in particular type annotations on resource and struct fields. | ||
These type updates are required to accurately reflect the way that the Cadence 1.0 data migrations will change | ||
the types of these fields' values, and the Cadence 1.0 upgrade validator will enforce that these upgrades are accurate. | ||
|
||
## Restricted Types | ||
|
||
In Cadence 1.0, support for restricted types was dropped, and replaced with [intersection types](https://cadence-lang.org/docs/1.0/language/intersection-types). | ||
As such, any existing restricted types must be replaced with a different type. | ||
During the automated state migration for the Cadence 1.0 upgrade, restricted typed-values will be migrated according to a specific set of rules, and all developers must update the types in their contracts to mirror this. | ||
|
||
* `AnyStruct{I}` and `AnyResource{I}` should be migrated to just `{I}`, as these types have identical behavior | ||
* For any other type `T`, `T{I}` should be migrated to `T`, as this is the most specific possible type that can go here | ||
* For any type `T`, `T{}` should be migrated to just `T`, as there is no support for empty intersection types | ||
|
||
So, for example, a value of type `FlowToken.Vault{FungibleToken.Receiver}` should be migrated to just a `FlowToken.Vault` type, | ||
while a value of type `AnyResource{Provider, Receiver}` should be migrated to a `{Provider, Receiver}` intersection. | ||
|
||
## Reference Types | ||
|
||
Reference types (whether on their own like `&FlowToken.Vault` or within a capability type like `Capability<&FlowToken.Vault{FungibleToken.Provider}>`) | ||
from contracts written in Cadence v0.42 will need to be given | ||
[entitlements](https://cadence-lang.org/docs/1.0/language/access-control#entitlements) in order to retain the same functionality | ||
in Cadence 1.0. | ||
The Cadence 1.0 automated data migration will automatically grant the appropriate entitlements to stored values, | ||
but any reference types that appear in your contracts will need to be manually updated. | ||
|
||
The update you will need to perform involves changing each reference type to have the appropriate entitlements necessary to perform | ||
the same operations in Cadence 1.0 that it previously could in Cadence v0.42. | ||
The Cadence 1.0 upgrade validator will enforce that these upgrades are accurate, and will suggest the correct type in case of an error. | ||
However, if you'd like to understand how the validator computes this type, the next section has a technical explanation of what the validator is computing. | ||
|
||
### How the Validator Computes Entitlements | ||
|
||
The first basic concept necessary to understand the upgrade is the "entitlements function"; | ||
i.e. a hypothetical function that computes the set of entitlements that are valid for some composite or interface type `T`. | ||
This is just the complete set of entitlements that appear in that type's definition. | ||
|
||
E.g., for a resource type `R` defined as: | ||
|
||
```cadence | ||
access(all) resource R { | ||
access(E) fun foo() { ... } | ||
access(G | H) fun bar() { ... } | ||
} | ||
``` | ||
|
||
`Entitlements(I)` would be equal to `{E, G, H}`, i.e. all the entitlements that appear in `I`'s definition. | ||
The idea here is that any reference that was previously typed as `&R` was originally able to call all | ||
the `pub` functions in `R` (here both `foo` and `bar`), and after the Cadence 1.0 migration we want that to still be the case. | ||
In order to make that true, we need to give the `&R` all the entitlements it might need to do that, which is exactly `Entitlements(R)`. | ||
|
||
All of which is to say, any `&R` reference types that appear in your contract must be updated to `auth(E1, E2, ...) &R`, where `E1, E2, ...` are all | ||
the entitlements in `Entitlements(R)`. | ||
|
||
One important note is that reference to restricted types (`&T{I}`) behave slightly differently; instead of being given entitlements to `T`, they | ||
are instead granted only entitlements based on the interfaces in the restriction set (here `{I}`). So for some interface and composite defined like so: | ||
|
||
```cadence | ||
access(all) resource interface I { | ||
access(E) fun foo() | ||
} | ||
access(all) resource R: I { | ||
access(E) fun foo() { ... } | ||
access(F) fun bar() { ... } | ||
} | ||
``` | ||
|
||
A type `&R{I}` should be updated to `auth(E) &R`, since the entitlements it is given is only those in `I`. It does not receive an entitlement to `F`, since | ||
the old `&R{I}` was not able to call `bar`. |