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

FLIP for removing restricted types #85

Merged
merged 8 commits into from
Jun 21, 2023
69 changes: 69 additions & 0 deletions cadence/20230505-remove-restricted-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
status: accepted
flip: 85
authors: Daniel Sainati ([email protected])
sponsor: Daniel Sainati ([email protected])
updated: 2023-05-05
---

# FLIP 85: Replace Restricted Types with Interface Set Types

## Objective

Currently in Cadence, a restricted type consists of a type (often confusingly also called
the restricted type) and a set of interface types that serve as its restrictions. Written `T{I1, I2, ...}`,
this type indicates a value of type `T`, but restricted such that only members present on one of the `I`s
can be accessed. This FLIP proposes to remove the `T` portion of the type, changing this type to simply
indicate some value of a type that conforms to each of the `I`s.

## Motivation

The proposed entitlements changes in [the entitlements FLIP](https://github.com/onflow/flips/pull/54) make
restricted types mostly useless in their current form. Previously they existed as a form of access control for references,
as a restricted reference type could not be downcast, so a restriction set functioned for references like access control,
limiting what functionality was available to a reference.

The entitlements changes will move this functionality to entitlements, and allow downcasting references, making
this behavior unnecessary. However, it will still be valuable to allow the specification of "interface set" types,
for the purposes of polymorphism, so by removing the outer `T` component of the restricted type `T{I1, I2, ...}`, we
can replace this obseleted type form with a simpler interface set type that handles the polymorphism use case.

## User Benefit

This will simplify the language by removing a redundant and poorly understood feature.

## Design Proposal

This would remove the "restricted type" portion of the restricted type. Users will no longer be able to write types with a `T` in
the `T{I}` position of an old restricted type.

For the new semantics of the interface set type, we can use the existing semantics of the `AnyStruct{X}` and `AnyResource{Y}` restricted types,
as these contain no information about the type being restricted, and thus function only as restrictions on a generic type.
dsainati1 marked this conversation as resolved.
Show resolved Hide resolved

The semantics of upcasting and downcasting restricted types will remain the same; they will be covariant in their interface sets.

Existing references and capabilities could be migrated by replacing the restricted type with the outer type, i.e. converting `T{I}` to `T`.
In combination with the incoming entitlement changes, where the old "restricted" behavior would be recaptured with entitlements, this would
be able to preserve existing behavior. In particular, in the case of references, the entitlements present on the interfaces would be granted to the
reference type.
dsainati1 marked this conversation as resolved.
Show resolved Hide resolved

For example, an existing `&Vault{Withdraw}` value would be migrated to a `auth(Withdrawable) &Vault` reference

### Drawbacks

This is not backwards compatible, and will break existing restricted types that have non-trivial values for their outer type.

### Alternatives Considered

We could simply leave restricted types as-is, which would break nothing, but would leave restricted types in the language
as a vestigial feature without much of a use case.

### Compatibility

This is not backwards compatible.

### User Impact

As users are already going to be needing to rethink their restricted types as they migrate their contracts to use
entitlements, this is unlikely to significantly increase the engineering burden of upgrading their contracts to Stable
Cadence.