From 74b1010905ea336421dc30dbe455ecde58d6e0c7 Mon Sep 17 00:00:00 2001 From: Supun Setunga Date: Fri, 16 Feb 2024 11:18:07 +0530 Subject: [PATCH] Require converting empty set T{} to T --- ..._to_v1_contract_upgrade_validation_test.go | 30 +++++++++++++++++++ ..._v0.42_to_v1_contract_upgrade_validator.go | 15 ++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go index 0019a6789..11d878919 100644 --- a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go +++ b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validation_test.go @@ -849,6 +849,36 @@ func TestContractUpgradeIntersectionFieldType(t *testing.T) { require.NoError(t, err) }) + t.Run("AnyResource restricted type, without restrictions", func(t *testing.T) { + + t.Parallel() + + const oldCode = ` + pub contract Test { + pub resource R {} + + pub var a: @AnyResource{} + init() { + self.a <- create R() + } + } + ` + + const newCode = ` + access(all) contract Test { + access(all) resource R {} + + access(all) var a: @AnyResource + init() { + self.a <- create R() + } + } + ` + + err := testContractUpdate(t, oldCode, newCode) + require.NoError(t, err) + }) + t.Run("change field type restricted type variable sized", func(t *testing.T) { t.Parallel() diff --git a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go index 025896a91..d7ab8ae08 100644 --- a/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go +++ b/runtime/stdlib/cadence_v0.42_to_v1_contract_upgrade_validator.go @@ -285,17 +285,22 @@ typeSwitch: validator.currentRestrictedTypeUpgradeRestrictions = oldType.Types // If the old restricted type is for AnyStruct/AnyResource, - // require them to drop the "restricted type". - // e.g: `T{I} -> {I}` + // and if there are atleast one restriction, require them to drop the "restricted type". + // e.g-1: `AnyStruct{I} -> {I}` + // e.g-2: `AnyResource{I} -> {I}` + // See: https://github.com/onflow/cadence/issues/3112 if restrictedNominalType, isNominal := oldType.LegacyRestrictedType.(*ast.NominalType); isNominal { switch restrictedNominalType.Identifier.Identifier { case "AnyStruct", "AnyResource": - break typeSwitch + if len(oldType.Types) > 0 { + break typeSwitch + } } } - // Otherwise require them to drop the "restriction". - // e.g: `T{I} -> T` + // Otherwise require them to drop the "restrictions". + // e.g-1: `T{I} -> T` + // e.g-2: `AnyStruct{} -> AnyStruct` return validator.checkTypeUpgradability(oldType.LegacyRestrictedType, newType) case *ast.VariableSizedType: