Skip to content

Commit

Permalink
make Any type, AnyResource type, and AnyStruct type singletons
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Feb 24, 2021
1 parent 8ca17c0 commit 26b1db1
Show file tree
Hide file tree
Showing 29 changed files with 417 additions and 537 deletions.
12 changes: 6 additions & 6 deletions runtime/convertTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ func ExportType(t sema.Type, results map[sema.TypeID]cadence.Type) cadence.Type

result := func() cadence.Type {
switch t := t.(type) {
case *sema.AnyType:
return cadence.AnyType{}
case *sema.AnyStructType:
return cadence.AnyStructType{}
case *sema.AnyResourceType:
return cadence.AnyResourceType{}
case *sema.OptionalType:
return exportOptionalType(t, results)
case *sema.StringType:
Expand Down Expand Up @@ -152,6 +146,12 @@ func ExportType(t sema.Type, results map[sema.TypeID]cadence.Type) cadence.Type
return cadence.BoolType{}
case sema.CharacterType:
return cadence.CharacterType{}
case sema.AnyType:
return cadence.AnyType{}
case sema.AnyStructType:
return cadence.AnyStructType{}
case sema.AnyResourceType:
return cadence.AnyResourceType{}
}

panic(fmt.Sprintf("cannot export type of type %T", t))
Expand Down
144 changes: 58 additions & 86 deletions runtime/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,8 +828,8 @@ func (interpreter *Interpreter) prepareInvoke(
for i, argument := range arguments {
parameterType := parameters[i].TypeAnnotation.Type
// TODO: value type is not known, reject for now
switch parameterType.(type) {
case *sema.AnyStructType, *sema.AnyResourceType:
switch parameterType {
case sema.AnyStructType, sema.AnyResourceType:
return nil, NotInvokableError{
Value: functionValue,
}
Expand Down Expand Up @@ -3806,44 +3806,37 @@ func (interpreter *Interpreter) newConverterFunction(converter ValueConverter) F
func IsSubType(subType DynamicType, superType sema.Type) bool {
switch typedSubType := subType.(type) {
case MetaTypeDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
switch superType {
case sema.AnyStructType, sema.MetaType:
return true
}

return superType == sema.MetaType

case VoidDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
switch superType {
case sema.AnyStructType, sema.VoidType:
return true
}

return superType == sema.VoidType

case StringDynamicType:
switch superType.(type) {
case *sema.StringType, *sema.AnyStructType:
if _, ok := superType.(*sema.StringType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case BoolDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
switch superType {
case sema.AnyStructType, sema.BoolType:
return true
}

return superType == sema.BoolType

case AddressDynamicType:
switch superType.(type) {
case *sema.AddressType, *sema.AnyStructType:
if _, ok := superType.(*sema.AddressType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case NumberDynamicType:
return sema.IsSubType(typedSubType.StaticType, superType)

Expand All @@ -3860,11 +3853,13 @@ func IsSubType(subType DynamicType, superType sema.Type) bool {
case *sema.ConstantSizedType:
superTypeElementType = typedSuperType.Type

case *sema.AnyStructType, *sema.AnyResourceType:
return true

default:
return false
switch superType {
case sema.AnyStructType, sema.AnyResourceType:
return true
default:
return false
}
}

for _, elementType := range typedSubType.ElementTypes {
Expand All @@ -3877,8 +3872,7 @@ func IsSubType(subType DynamicType, superType sema.Type) bool {

case DictionaryDynamicType:

switch typedSuperType := superType.(type) {
case *sema.DictionaryType:
if typedSuperType, ok := superType.(*sema.DictionaryType); ok {
for _, entryTypes := range typedSubType.EntryTypes {
if !IsSubType(entryTypes.KeyType, typedSuperType.KeyType) ||
!IsSubType(entryTypes.ValueType, typedSuperType.ValueType) {
Expand All @@ -3888,59 +3882,57 @@ func IsSubType(subType DynamicType, superType sema.Type) bool {
}

return true
}

case *sema.AnyStructType, *sema.AnyResourceType:
switch superType {
case sema.AnyStructType, sema.AnyResourceType:
return true

default:
return false
}

case NilDynamicType:
switch superType.(type) {
case *sema.OptionalType, *sema.AnyStructType, *sema.AnyResourceType:
if _, ok := superType.(*sema.OptionalType); ok {
return true
}

switch superType {
case sema.AnyStructType, sema.AnyResourceType:
return true

default:
return false
}

case SomeDynamicType:
switch typedSuperType := superType.(type) {
case *sema.OptionalType:
if typedSuperType, ok := superType.(*sema.OptionalType); ok {
return IsSubType(typedSubType.InnerType, typedSuperType.Type)
}

case *sema.AnyStructType, *sema.AnyResourceType:
switch superType {
case sema.AnyStructType, sema.AnyResourceType:
return true

default:
return false
}

case ReferenceDynamicType:
switch typedSuperType := superType.(type) {
case *sema.AnyStructType:
return true

case *sema.ReferenceType:
if typedSuperType, ok := superType.(*sema.ReferenceType); ok {
if typedSubType.Authorized() {
return IsSubType(typedSubType.InnerType(), typedSuperType.Type)
} else {
// NOTE: Allowing all casts for casting unauthorized references is intentional:
// all invalid cases have already been rejected statically
return true
}

default:
return false
}

case CapabilityDynamicType:
switch typedSuperType := superType.(type) {
case *sema.AnyStructType:
return true
return superType == sema.AnyStructType

case *sema.CapabilityType:
case CapabilityDynamicType:
if typedSuperType, ok := superType.(*sema.CapabilityType); ok {

if typedSuperType.BorrowType != nil {

Expand All @@ -3967,86 +3959,66 @@ func IsSubType(subType DynamicType, superType sema.Type) bool {

}

case PublicPathDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
return true
}
return superType == sema.AnyStructType

case PublicPathDynamicType:
switch superType {
case sema.PublicPathType, sema.CapabilityPathType, sema.PathType:
case sema.PublicPathType, sema.CapabilityPathType, sema.PathType, sema.AnyStructType:
return true
default:
return false
}

case PrivatePathDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
return true
}

switch superType {
case sema.PrivatePathType, sema.CapabilityPathType, sema.PathType:
case sema.PrivatePathType, sema.CapabilityPathType, sema.PathType, sema.AnyStructType:
return true
default:
return false
}

case StoragePathDynamicType:
if _, ok := superType.(*sema.AnyStructType); ok {
return true
}

switch superType {
case sema.StoragePathType, sema.PathType:
case sema.StoragePathType, sema.PathType, sema.AnyStructType:
return true
default:
return false
}

case PublicAccountDynamicType:
switch superType.(type) {
case *sema.PublicAccountType, *sema.AnyStructType:
if _, ok := superType.(*sema.PublicAccountType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case AuthAccountDynamicType:
switch superType.(type) {
case *sema.AuthAccountType, *sema.AnyStructType:
if _, ok := superType.(*sema.AuthAccountType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case DeployedContractDynamicType:
switch superType.(type) {
case *sema.DeployedContractType, *sema.AnyStructType:
if _, ok := superType.(*sema.DeployedContractType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case AuthAccountContractsDynamicType:
switch superType.(type) {
case *sema.AuthAccountContractsType, *sema.AnyStructType:
if _, ok := superType.(*sema.AuthAccountContractsType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType

case BlockDynamicType:
switch superType.(type) {
case *sema.BlockType, *sema.AnyStructType:
if _, ok := superType.(*sema.BlockType); ok {
return true

default:
return false
}

return superType == sema.AnyStructType
}

return false
Expand Down
4 changes: 2 additions & 2 deletions runtime/interpreter/interpreter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ func TestInterpreterBoxing(t *testing.T) {
require.NoError(t, err)

for _, anyType := range []sema.Type{
&sema.AnyStructType{},
&sema.AnyResourceType{},
sema.AnyStructType,
sema.AnyResourceType,
} {

t.Run(anyType.String(), func(t *testing.T) {
Expand Down
21 changes: 9 additions & 12 deletions runtime/interpreter/primitivestatictype.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,16 @@ func (i PrimitiveStaticType) SemaType() sema.Type {
return sema.VoidType

case PrimitiveStaticTypeAny:
return &sema.AnyType{}
return sema.AnyType

case PrimitiveStaticTypeNever:
return sema.NeverType

case PrimitiveStaticTypeAnyStruct:
return &sema.AnyStructType{}
return sema.AnyStructType

case PrimitiveStaticTypeAnyResource:
return &sema.AnyResourceType{}
return sema.AnyResourceType

case PrimitiveStaticTypeBool:
return sema.BoolType
Expand Down Expand Up @@ -299,15 +299,6 @@ func (i PrimitiveStaticType) SemaType() sema.Type {
//
func ConvertSemaToPrimitiveStaticType(t sema.Type) PrimitiveStaticType {
switch t.(type) {
case *sema.AnyType:
return PrimitiveStaticTypeAny

case *sema.AnyStructType:
return PrimitiveStaticTypeAnyStruct

case *sema.AnyResourceType:
return PrimitiveStaticTypeAnyResource

case *sema.AddressType:
return PrimitiveStaticTypeAddress

Expand Down Expand Up @@ -422,6 +413,12 @@ func ConvertSemaToPrimitiveStaticType(t sema.Type) PrimitiveStaticType {
return PrimitiveStaticTypeBool
case sema.CharacterType:
return PrimitiveStaticTypeCharacter
case sema.AnyType:
return PrimitiveStaticTypeAny
case sema.AnyStructType:
return PrimitiveStaticTypeAnyStruct
case sema.AnyResourceType:
return PrimitiveStaticTypeAnyResource
}

return PrimitiveStaticTypeUnknown
Expand Down
Loading

0 comments on commit 26b1db1

Please sign in to comment.