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

Fix migrating values with empty intersection type #3138

Merged
merged 13 commits into from
Mar 4, 2024

Conversation

turbolent
Copy link
Member

@turbolent turbolent commented Feb 26, 2024

Work towards #3096

Description

Migrated values may have empty intersection types, as they originally were restricted types, i.e. they have a legacy type.

Creating empty intersection types without (correctly) defensively panics, but prevents migrating values.

Removing the panic and only accepting empty intersection types is not enough: The resulting sema intersection type is then used for various purposes during the migration, e.g. subtype checking when inserting into a dictionary, performing the appropriate transfer (copy or move), etc.

Bring back the legacy type in sema.IntersectionType, just like it already exists in interpreter.StaticIntersectionType, and restore the subtyping rules which were removed in #2596 (see https:/onflow/cadence/pull/2596/files#diff-c01765841e64b85306258f5ee4daff2bdc5b9e9e107167f55a6dba4162e8bdb8).

The subtyping rules for Cadence 1.0 intersection type got integrated into the restored rules.

Because this is hard to review, I prepared a diff of the original subtyping rules for restricted types (taken from #2596) and the new subtying rules for intersection types of this PR:

diff --git a/sub-old.go b/sub-new.go
index 576c521b3..492288806 100644
--- a/sub-old.go
+++ b/sub-new.go
@@ -1,10 +1,32 @@
-intersectionSuperType := typedSuperType.Type
+	case *IntersectionType:
+
+		// TODO: replace with
+		//
+		//switch typedSubType := subType.(type) {
+		//case *IntersectionType:
+		//
+		//	// An intersection type `{Us}` is a subtype of an intersection type `{Vs}` / `{Vs}` / `{Vs}`:
+		//	// when `Vs` is a subset of `Us`.
+		//
+		//	return typedSuperType.EffectiveIntersectionSet().
+		//		IsSubsetOf(typedSubType.EffectiveIntersectionSet())
+		//
+		//case *CompositeType:
+		//	// A type `T` is a subtype of an intersection type `{Us}` / `{Us}` / `{Us}`:
+		//	// when `T` conforms to `Us`.
+		//
+		//	return typedSuperType.EffectiveIntersectionSet().
+		//		IsSubsetOf(typedSubType.EffectiveInterfaceConformanceSet())
+		//}
+
+		intersectionSuperType := typedSuperType.LegacyType //nolint:staticcheck
+
 		switch intersectionSuperType {
-		case AnyResourceType, AnyStructType, AnyType:
+		case nil, AnyResourceType, AnyStructType, AnyType:
 
 			switch subType {
 			case AnyResourceType:
-				// `AnyResource` is a subtype of a intersection type
+				// `AnyResource` is a subtype of an intersection type
 				// - `AnyResource{Us}`: not statically;
 				// - `AnyStruct{Us}`: never.
 				// - `Any{Us}`: not statically;
@@ -12,7 +34,7 @@ intersectionSuperType := typedSuperType.Type
 				return false
 
 			case AnyStructType:
-				// `AnyStruct` is a subtype of a intersection type
+				// `AnyStruct` is a subtype of an intersection type
 				// - `AnyStruct{Us}`: not statically.
 				// - `AnyResource{Us}`: never;
 				// - `Any{Us}`: not statically.
@@ -20,7 +42,7 @@ intersectionSuperType := typedSuperType.Type
 				return false
 
 			case AnyType:
-				// `Any` is a subtype of a intersection type
+				// `Any` is a subtype of an intersection type
 				// - `Any{Us}: not statically.`
 				// - `AnyStruct{Us}`: never;
 				// - `AnyResource{Us}`: never;
@@ -31,20 +53,32 @@ intersectionSuperType := typedSuperType.Type
 			switch typedSubType := subType.(type) {
 			case *IntersectionType:
 
-				// A intersection type `T{Us}`
-				// is a subtype of a intersection type `AnyResource{Vs}` / `AnyStruct{Vs}` / `Any{Vs}`:
+				// An intersection type `T{Us}`
+				// is a subtype of an intersection type `AnyResource{Vs}` / `AnyStruct{Vs}` / `Any{Vs}`:
 
-				intersectionSubtype := typedSubType.Type
+				intersectionSubtype := typedSubType.LegacyType //nolint:staticcheck
 				switch intersectionSubtype {
+				case nil:
+					// An intersection type `{Us}` is a subtype of an intersection type `{Vs}` / `{Vs}` / `{Vs}`:
+					// when `Vs` is a subset of `Us`.
+
+					return typedSuperType.EffectiveIntersectionSet().
+						IsSubsetOf(typedSubType.EffectiveIntersectionSet())
+
 				case AnyResourceType, AnyStructType, AnyType:
 					// When `T == AnyResource || T == AnyStruct || T == Any`:
 					// if the intersection type of the subtype
 					// is a subtype of the intersection supertype,
 					// and `Vs` is a subset of `Us`.
 
-					return IsSubType(intersectionSubtype, intersectionSuperType) &&
-						typedSuperType.EffectiveIntersectionSet().
-							IsSubsetOf(typedSubType.EffectiveIntersectionSet())
+					if intersectionSuperType != nil &&
+						!IsSubType(intersectionSubtype, intersectionSuperType) {
+
+						return false
+					}
+
+					return typedSuperType.EffectiveIntersectionSet().
+						IsSubsetOf(typedSubType.EffectiveIntersectionSet())
 				}
 
 				if intersectionSubtype, ok := intersectionSubtype.(*CompositeType); ok {
@@ -54,59 +88,71 @@ intersectionSuperType := typedSuperType.Type
 					// and `T` conforms to `Vs`.
 					// `Us` and `Vs` do *not* have to be subsets.
 
-					return IsSubType(intersectionSubtype, intersectionSuperType) &&
-						typedSuperType.EffectiveIntersectionSet().
-							IsSubsetOf(intersectionSubtype.EffectiveInterfaceConformanceSet())
+					if intersectionSuperType != nil &&
+						!IsSubType(intersectionSubtype, intersectionSuperType) {
+
+						return false
+					}
+
+					return typedSuperType.EffectiveIntersectionSet().
+						IsSubsetOf(intersectionSubtype.EffectiveInterfaceConformanceSet())
 				}
 
 			case *CompositeType:
 				// A type `T`
-				// is a subtype of a intersection type `AnyResource{Us}` / `AnyStruct{Us}` / `Any{Us}`:
+				// is a subtype of an intersection type `AnyResource{Us}` / `AnyStruct{Us}` / `Any{Us}`:
 				// if `T` is a subtype of the intersection supertype,
 				// and `T` conforms to `Us`.
 
-				return IsSubType(typedSubType, typedSuperType.Type) &&
-					typedSuperType.EffectiveIntersectionSet().
-						IsSubsetOf(typedSubType.EffectiveInterfaceConformanceSet())
+				if intersectionSuperType != nil &&
+					!IsSubType(typedSubType, intersectionSuperType) {
+
+					return false
+				}
+
+				return typedSuperType.EffectiveIntersectionSet().
+					IsSubsetOf(typedSubType.EffectiveInterfaceConformanceSet())
 			}
 
 		default:
+			// Supertype (intersection) has a non-Any* legacy type
 
 			switch typedSubType := subType.(type) {
 			case *IntersectionType:
 
-				// A intersection type `T{Us}`
-				// is a subtype of a intersection type `V{Ws}`:
+				// An intersection type `T{Us}`
+				// is a subtype of an intersection type `V{Ws}`:
 
-				switch typedSubType.Type {
-				case AnyResourceType, AnyStructType, AnyType:
+				intersectionSubType := typedSubType.LegacyType //nolint:staticcheck
+				switch intersectionSubType {
+				case nil, AnyResourceType, AnyStructType, AnyType:
 					// When `T == AnyResource || T == AnyStruct || T == Any`:
 					// not statically.
 					return false
 				}
 
-				if intersectionSubType, ok := typedSubType.Type.(*CompositeType); ok {
+				if intersectionSubType, ok := intersectionSubType.(*CompositeType); ok {
 					// When `T != AnyResource && T != AnyStructType && T != Any`: if `T == V`.
 					//
 					// `Us` and `Ws` do *not* have to be subsets:
 					// The owner may freely restrict and unrestrict.
 
-					return intersectionSubType == typedSuperType.Type
+					return intersectionSubType == intersectionSuperType
 				}
 
 			case *CompositeType:
 				// A type `T`
-				// is a subtype of a intersection type `U{Vs}`: if `T <: U`.
+				// is a subtype of an intersection type `U{Vs}`: if `T <: U`.
 				//
 				// The owner may freely restrict.
 
-				return IsSubType(typedSubType, typedSuperType.Type)
+				return IsSubType(typedSubType, intersectionSuperType)
 			}
 
 			switch subType {
 			case AnyResourceType, AnyStructType, AnyType:
 				// A type `T`
-				// is a subtype of a intersection type `AnyResource{Vs}` / `AnyStruct{Vs}` / `Any{Vs}`:
+				// is a subtype of an intersection type `AnyResource{Vs}` / `AnyStruct{Vs}` / `Any{Vs}`:
 				// not statically.
 
 				return false
@@ -114,21 +160,29 @@ intersectionSuperType := typedSuperType.Type
 		}
 
 	case *CompositeType:
+
 		// NOTE: type equality case (composite type `T` is subtype of composite type `U`)
 		// is already handled at beginning of function
+
 		switch typedSubType := subType.(type) {
 		case *IntersectionType:
 
-			// A intersection type `T{Us}`
+			// TODO: bring back once legacy type is removed
+			// An intersection type `{Us}` is never a subtype of a type `V`:
+			//return false
+
+			// TODO: remove support for legacy type
+			// An intersection type `T{Us}`
 			// is a subtype of a type `V`:
 
-			switch typedSubType.Type {
-			case AnyResourceType, AnyStructType, AnyType:
+			legacyType := typedSubType.LegacyType
+			switch legacyType {
+			case nil, AnyResourceType, AnyStructType, AnyType:
 				// When `T == AnyResource || T == AnyStruct || T == Any`: not statically.
 				return false
 			}
 
-			if intersectionSubType, ok := typedSubType.Type.(*CompositeType); ok {
+			if intersectionSubType, ok := legacyType.(*CompositeType); ok {
 				// When `T != AnyResource && T != AnyStruct`: if `T == V`.
 				//
 				// The owner may freely unrestrict.

  • 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

Copy link

github-actions bot commented Feb 26, 2024

Cadence Benchstat comparison

This branch with compared with the base branch onflow:master commit f605ce8
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
DecodeBatchEventsCCF-4129ms ± 0%129ms ± 0%~(p=1.000 n=1+1)
DecodeBatchEventsJSON-4410ms ± 0%400ms ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowFees.FeesDeducted-42.85µs ± 0%2.80µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowFees.TokensWithdrawn-42.13µs ± 0%2.14µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-42.83µs ± 0%2.78µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-43.19µs ± 0%3.08µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowIDTableStaking.NewWeeklyPayout-42.15µs ± 0%2.20µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowIDTableStaking.RewardsPaid-42.52µs ± 0%2.51µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowToken.TokensDeposited-42.59µs ± 0%2.58µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowToken.TokensDeposited_with_nil_receiver-42.52µs ± 0%2.49µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowToken.TokensMinted-42.14µs ± 0%2.14µs ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowToken.TokensWithdrawn-42.61µs ± 0%2.61µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowFees.FeesDeducted-49.89µs ± 0%9.81µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowFees.TokensWithdrawn-45.69µs ± 0%5.78µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-49.00µs ± 0%8.91µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-412.2µs ± 0%12.2µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowIDTableStaking.NewWeeklyPayout-45.87µs ± 0%5.82µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowIDTableStaking.RewardsPaid-47.57µs ± 0%7.52µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowToken.TokensDeposited-47.84µs ± 0%7.83µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowToken.TokensDeposited_with_nil_receiver-47.14µs ± 0%7.10µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowToken.TokensMinted-45.77µs ± 0%5.73µs ± 0%~(p=1.000 n=1+1)
DecodeJSON/FlowToken.TokensWithdrawn-47.86µs ± 0%7.82µs ± 0%~(p=1.000 n=1+1)
EncodeBatchEventsCCF-488.7ms ± 0%90.0ms ± 0%~(p=1.000 n=1+1)
EncodeBatchEventsJSON-4106ms ± 0%106ms ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowFees.FeesDeducted-41.97µs ± 0%2.01µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowFees.TokensWithdrawn-41.56µs ± 0%1.56µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-41.90µs ± 0%1.91µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-42.23µs ± 0%2.25µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowIDTableStaking.NewWeeklyPayout-41.61µs ± 0%1.59µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowIDTableStaking.RewardsPaid-41.74µs ± 0%1.75µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowToken.TokensDeposited-41.79µs ± 0%1.81µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowToken.TokensDeposited_with_nil_receiver-41.77µs ± 0%1.79µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowToken.TokensMinted-41.56µs ± 0%1.55µs ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowToken.TokensWithdrawn-41.81µs ± 0%1.82µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowFees.FeesDeducted-42.47µs ± 0%2.48µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowFees.TokensWithdrawn-41.42µs ± 0%1.42µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-42.25µs ± 0%2.46µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-43.11µs ± 0%3.10µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowIDTableStaking.NewWeeklyPayout-41.45µs ± 0%1.47µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowIDTableStaking.RewardsPaid-41.89µs ± 0%1.90µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowToken.TokensDeposited-42.19µs ± 0%2.22µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowToken.TokensDeposited_with_nil_receiver-41.70µs ± 0%1.71µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowToken.TokensMinted-41.44µs ± 0%1.45µs ± 0%~(p=1.000 n=1+1)
EncodeJSON/FlowToken.TokensWithdrawn-42.13µs ± 0%2.15µs ± 0%~(p=1.000 n=1+1)
ExportType/composite_type-4274ns ± 0%287ns ± 0%~(p=1.000 n=1+1)
ExportType/simple_type-471.0ns ± 0%70.9ns ± 0%~(p=1.000 n=1+1)
InterpretRecursionFib-42.31ms ± 0%2.14ms ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_interpreter-4907ns ± 0%1014ns ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_sub-interpreter-4457ns ± 0%443ns ± 0%~(p=1.000 n=1+1)
ParseArray-45.96ms ± 1%5.91ms ± 0%~(p=0.333 n=2+2)
ParseDeploy/byte_array-49.02ms ± 0%8.89ms ± 0%~(p=0.333 n=2+2)
ParseDeploy/decode_hex-4986µs ± 0%1004µs ± 2%~(p=0.667 n=2+2)
ParseFungibleToken/With_memory_metering-4150µs ± 5%150µs ± 2%~(p=1.000 n=2+2)
ParseFungibleToken/Without_memory_metering-4115µs ± 3%115µs ± 3%~(p=1.000 n=2+2)
ParseInfix-45.22µs ± 0%5.36µs ± 2%~(p=0.333 n=2+2)
QualifiedIdentifierCreation/One_level-42.48ns ± 0%2.48ns ± 0%~(p=1.000 n=1+1)
QualifiedIdentifierCreation/Three_levels-483.8ns ± 0%83.4ns ± 0%~(p=1.000 n=1+1)
RuntimeScriptNoop-43.63µs ± 0%3.70µs ± 0%~(p=1.000 n=1+1)
SuperTypeInference/arrays-4241ns ± 0%240ns ± 0%~(p=1.000 n=1+1)
SuperTypeInference/composites-489.5ns ± 0%86.3ns ± 0%~(p=1.000 n=1+1)
SuperTypeInference/integers-4314ns ± 0%313ns ± 0%~(p=1.000 n=1+1)
ValueIsSubtypeOfSemaType-477.7ns ± 0%70.7ns ± 0%~(p=1.000 n=1+1)
 
alloc/opdelta
DecodeBatchEventsCCF-466.5MB ± 0%66.5MB ± 0%~(p=1.000 n=1+1)
DecodeBatchEventsJSON-4244MB ± 0%244MB ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowFees.FeesDeducted-41.40kB ± 0%1.40kB ± 0%~(all equal)
DecodeCCF/FlowFees.TokensWithdrawn-41.21kB ± 0%1.21kB ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-41.48kB ± 0%1.48kB ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-41.49kB ± 0%1.49kB ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.NewWeeklyPayout-41.26kB ± 0%1.26kB ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.RewardsPaid-41.38kB ± 0%1.38kB ± 0%~(all equal)
DecodeCCF/FlowToken.TokensDeposited-41.32kB ± 0%1.32kB ± 0%~(all equal)
DecodeCCF/FlowToken.TokensDeposited_with_nil_receiver-41.30kB ± 0%1.30kB ± 0%~(all equal)
DecodeCCF/FlowToken.TokensMinted-41.21kB ± 0%1.21kB ± 0%~(all equal)
DecodeCCF/FlowToken.TokensWithdrawn-41.33kB ± 0%1.33kB ± 0%~(all equal)
DecodeJSON/FlowFees.FeesDeducted-46.00kB ± 0%6.00kB ± 0%~(all equal)
DecodeJSON/FlowFees.TokensWithdrawn-43.60kB ± 0%3.60kB ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-45.43kB ± 0%5.43kB ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-47.35kB ± 0%7.35kB ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.NewWeeklyPayout-43.64kB ± 0%3.64kB ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.RewardsPaid-44.54kB ± 0%4.54kB ± 0%~(all equal)
DecodeJSON/FlowToken.TokensDeposited-44.88kB ± 0%4.88kB ± 0%~(all equal)
DecodeJSON/FlowToken.TokensDeposited_with_nil_receiver-44.46kB ± 0%4.46kB ± 0%~(all equal)
DecodeJSON/FlowToken.TokensMinted-43.60kB ± 0%3.60kB ± 0%~(all equal)
DecodeJSON/FlowToken.TokensWithdrawn-44.88kB ± 0%4.88kB ± 0%~(all equal)
EncodeBatchEventsCCF-462.4MB ± 0%62.4MB ± 0%~(p=1.000 n=1+1)
EncodeBatchEventsJSON-439.1MB ± 0%39.1MB ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowFees.FeesDeducted-41.22kB ± 0%1.22kB ± 0%~(all equal)
EncodeCCF/FlowFees.TokensWithdrawn-41.17kB ± 0%1.17kB ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-41.44kB ± 0%1.44kB ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-41.41kB ± 0%1.41kB ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.NewWeeklyPayout-41.34kB ± 0%1.34kB ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.RewardsPaid-41.42kB ± 0%1.42kB ± 0%~(all equal)
EncodeCCF/FlowToken.TokensDeposited-41.22kB ± 0%1.22kB ± 0%~(all equal)
EncodeCCF/FlowToken.TokensDeposited_with_nil_receiver-41.20kB ± 0%1.20kB ± 0%~(all equal)
EncodeCCF/FlowToken.TokensMinted-41.17kB ± 0%1.17kB ± 0%~(all equal)
EncodeCCF/FlowToken.TokensWithdrawn-41.22kB ± 0%1.22kB ± 0%~(all equal)
EncodeJSON/FlowFees.FeesDeducted-4864B ± 0%864B ± 0%~(all equal)
EncodeJSON/FlowFees.TokensWithdrawn-4504B ± 0%504B ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-4888B ± 0%888B ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-41.08kB ± 0%1.08kB ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.NewWeeklyPayout-4552B ± 0%552B ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.RewardsPaid-4752B ± 0%752B ± 0%~(all equal)
EncodeJSON/FlowToken.TokensDeposited-4776B ± 0%776B ± 0%~(all equal)
EncodeJSON/FlowToken.TokensDeposited_with_nil_receiver-4640B ± 0%640B ± 0%~(all equal)
EncodeJSON/FlowToken.TokensMinted-4512B ± 0%512B ± 0%~(all equal)
EncodeJSON/FlowToken.TokensWithdrawn-4768B ± 0%768B ± 0%~(all equal)
ExportType/composite_type-4120B ± 0%120B ± 0%~(all equal)
ExportType/simple_type-40.00B 0.00B ~(all equal)
InterpretRecursionFib-41.00MB ± 0%1.00MB ± 0%~(p=1.000 n=1+1)
NewInterpreter/new_interpreter-4944B ± 0%944B ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-4200B ± 0%200B ± 0%~(all equal)
ParseArray-42.65MB ± 0%2.68MB ± 1%~(p=0.667 n=2+2)
ParseDeploy/byte_array-44.15MB ± 2%4.22MB ± 0%~(p=0.333 n=2+2)
ParseDeploy/decode_hex-4214kB ± 0%214kB ± 0%~(p=0.333 n=2+2)
ParseFungibleToken/With_memory_metering-429.6kB ± 0%29.6kB ± 0%~(p=1.000 n=2+2)
ParseFungibleToken/Without_memory_metering-429.6kB ± 0%29.6kB ± 0%~(p=0.667 n=2+2)
ParseInfix-41.92kB ± 0%1.92kB ± 0%~(p=1.000 n=2+2)
QualifiedIdentifierCreation/One_level-40.00B 0.00B ~(all equal)
QualifiedIdentifierCreation/Three_levels-464.0B ± 0%64.0B ± 0%~(all equal)
RuntimeScriptNoop-43.21kB ± 0%3.21kB ± 0%~(all equal)
SuperTypeInference/arrays-496.0B ± 0%96.0B ± 0%~(all equal)
SuperTypeInference/composites-40.00B 0.00B ~(all equal)
SuperTypeInference/integers-40.00B 0.00B ~(all equal)
ValueIsSubtypeOfSemaType-448.0B ± 0%48.0B ± 0%~(all equal)
 
allocs/opdelta
DecodeBatchEventsCCF-41.48M ± 0%1.48M ± 0%~(all equal)
DecodeBatchEventsJSON-44.70M ± 0%4.70M ± 0%~(p=1.000 n=1+1)
DecodeCCF/FlowFees.FeesDeducted-430.0 ± 0%30.0 ± 0%~(all equal)
DecodeCCF/FlowFees.TokensWithdrawn-426.0 ± 0%26.0 ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-430.0 ± 0%30.0 ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-432.0 ± 0%32.0 ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.NewWeeklyPayout-426.0 ± 0%26.0 ± 0%~(all equal)
DecodeCCF/FlowIDTableStaking.RewardsPaid-429.0 ± 0%29.0 ± 0%~(all equal)
DecodeCCF/FlowToken.TokensDeposited-431.0 ± 0%31.0 ± 0%~(all equal)
DecodeCCF/FlowToken.TokensDeposited_with_nil_receiver-429.0 ± 0%29.0 ± 0%~(all equal)
DecodeCCF/FlowToken.TokensMinted-426.0 ± 0%26.0 ± 0%~(all equal)
DecodeCCF/FlowToken.TokensWithdrawn-431.0 ± 0%31.0 ± 0%~(all equal)
DecodeJSON/FlowFees.FeesDeducted-4126 ± 0%126 ± 0%~(all equal)
DecodeJSON/FlowFees.TokensWithdrawn-471.0 ± 0%71.0 ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-4102 ± 0%102 ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-4159 ± 0%159 ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.NewWeeklyPayout-470.0 ± 0%70.0 ± 0%~(all equal)
DecodeJSON/FlowIDTableStaking.RewardsPaid-487.0 ± 0%87.0 ± 0%~(all equal)
DecodeJSON/FlowToken.TokensDeposited-495.0 ± 0%95.0 ± 0%~(all equal)
DecodeJSON/FlowToken.TokensDeposited_with_nil_receiver-486.0 ± 0%86.0 ± 0%~(all equal)
DecodeJSON/FlowToken.TokensMinted-471.0 ± 0%71.0 ± 0%~(all equal)
DecodeJSON/FlowToken.TokensWithdrawn-495.0 ± 0%95.0 ± 0%~(all equal)
EncodeBatchEventsCCF-4950k ± 0%950k ± 0%~(p=1.000 n=1+1)
EncodeBatchEventsJSON-4853k ± 0%853k ± 0%~(p=1.000 n=1+1)
EncodeCCF/FlowFees.FeesDeducted-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowFees.TokensWithdrawn-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.DelegatorRewardsPaid-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.EpochTotalRewardsPaid-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.NewWeeklyPayout-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowIDTableStaking.RewardsPaid-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowToken.TokensDeposited-420.0 ± 0%20.0 ± 0%~(all equal)
EncodeCCF/FlowToken.TokensDeposited_with_nil_receiver-420.0 ± 0%20.0 ± 0%~(all equal)
EncodeCCF/FlowToken.TokensMinted-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeCCF/FlowToken.TokensWithdrawn-420.0 ± 0%20.0 ± 0%~(all equal)
EncodeJSON/FlowFees.FeesDeducted-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeJSON/FlowFees.TokensWithdrawn-412.0 ± 0%12.0 ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.DelegatorRewardsPaid-416.0 ± 0%16.0 ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.EpochTotalRewardsPaid-425.0 ± 0%25.0 ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.NewWeeklyPayout-412.0 ± 0%12.0 ± 0%~(all equal)
EncodeJSON/FlowIDTableStaking.RewardsPaid-415.0 ± 0%15.0 ± 0%~(all equal)
EncodeJSON/FlowToken.TokensDeposited-419.0 ± 0%19.0 ± 0%~(all equal)
EncodeJSON/FlowToken.TokensDeposited_with_nil_receiver-414.0 ± 0%14.0 ± 0%~(all equal)
EncodeJSON/FlowToken.TokensMinted-413.0 ± 0%13.0 ± 0%~(all equal)
EncodeJSON/FlowToken.TokensWithdrawn-418.0 ± 0%18.0 ± 0%~(all equal)
ExportType/composite_type-43.00 ± 0%3.00 ± 0%~(all equal)
ExportType/simple_type-40.00 0.00 ~(all equal)
InterpretRecursionFib-418.9k ± 0%18.9k ± 0%~(all equal)
NewInterpreter/new_interpreter-415.0 ± 0%15.0 ± 0%~(all equal)
NewInterpreter/new_sub-interpreter-44.00 ± 0%4.00 ± 0%~(all equal)
ParseArray-459.6k ± 0%59.6k ± 0%~(p=0.667 n=2+2)
ParseDeploy/byte_array-489.4k ± 0%89.4k ± 0%~(p=0.667 n=2+2)
ParseDeploy/decode_hex-463.0 ± 0%63.0 ± 0%~(all equal)
ParseFungibleToken/With_memory_metering-4773 ± 1%773 ± 1%~(p=1.000 n=2+2)
ParseFungibleToken/Without_memory_metering-4773 ± 1%773 ± 1%~(p=1.000 n=2+2)
ParseInfix-448.0 ± 0%48.0 ± 0%~(all equal)
QualifiedIdentifierCreation/One_level-40.00 0.00 ~(all equal)
QualifiedIdentifierCreation/Three_levels-42.00 ± 0%2.00 ± 0%~(all equal)
RuntimeScriptNoop-451.0 ± 0%51.0 ± 0%~(all equal)
SuperTypeInference/arrays-43.00 ± 0%3.00 ± 0%~(all equal)
SuperTypeInference/composites-40.00 0.00 ~(all equal)
SuperTypeInference/integers-40.00 0.00 ~(all equal)
ValueIsSubtypeOfSemaType-41.00 ± 0%1.00 ± 0%~(all equal)
 

@turbolent turbolent changed the title Fix migration values with empty intersection type Fix migrating values with empty intersection type Feb 27, 2024
@turbolent turbolent self-assigned this Feb 27, 2024
@turbolent turbolent marked this pull request as ready for review February 27, 2024 22:44
intersectionSuperType := typedSuperType.LegacyType //nolint:staticcheck

switch intersectionSuperType {
case nil, AnyResourceType, AnyStructType, AnyType:
Copy link
Member Author

Choose a reason for hiding this comment

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

Integrated handling for no legacy type, see diff in description

Comment on lines +7721 to +7726
case nil:
// An intersection type `{Us}` is a subtype of an intersection type `{Vs}` / `{Vs}` / `{Vs}`:
// when `Vs` is a subset of `Us`.

return typedSuperType.EffectiveIntersectionSet().
IsSubsetOf(typedSubType.EffectiveIntersectionSet())
Copy link
Member Author

Choose a reason for hiding this comment

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

Integrated rule for no legacy type. Same as commented out code at top

Comment on lines +7734 to +7735
if intersectionSuperType != nil &&
!IsSubType(intersectionSubtype, intersectionSuperType) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Added support for no legacy type

Comment on lines +7751 to +7752
if intersectionSuperType != nil &&
!IsSubType(intersectionSubtype, intersectionSuperType) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Added support for no legacy type

Comment on lines +7767 to +7768
if intersectionSuperType != nil &&
!IsSubType(typedSubType, intersectionSuperType) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Added support for no legacy type


intersectionSubType := typedSubType.LegacyType //nolint:staticcheck
switch intersectionSubType {
case nil, AnyResourceType, AnyStructType, AnyType:
Copy link
Member Author

Choose a reason for hiding this comment

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

Integrated rule for no legacy type

// `Us` and `Ws` do *not* have to be subsets:
// The owner may freely restrict and unrestrict.

return intersectionSubType == intersectionSuperType
Copy link
Member Author

Choose a reason for hiding this comment

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

Both intersectionSubType and intersectionSuperType are non-nil here

Copy link

codecov bot commented Feb 27, 2024

Codecov Report

Attention: Patch coverage is 59.50413% with 98 lines in your changes are missing coverage. Please review.

Project coverage is 80.53%. Comparing base (f605ce8) to head (574c0df).

Files Patch % Lines
runtime/sema/type.go 54.26% 73 Missing and 2 partials ⚠️
runtime/interpreter/value_pathcapability.go 0.00% 17 Missing ⚠️
runtime/interpreter/statictype.go 86.95% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3138      +/-   ##
==========================================
- Coverage   80.60%   80.53%   -0.07%     
==========================================
  Files         381      381              
  Lines       92456    92616     +160     
==========================================
+ Hits        74520    74585      +65     
- Misses      15235    15327      +92     
- Partials     2701     2704       +3     
Flag Coverage Δ
unittests 80.53% <59.50%> (-0.07%) ⬇️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@turbolent turbolent merged commit 7eccaf4 into master Mar 4, 2024
11 of 14 checks passed
@turbolent turbolent deleted the bastian/fix-empty-intersection-type-migration branch March 4, 2024 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants