diff --git a/Crater/SemanticAnalysis/Types/ArrayType.cs b/Crater/SemanticAnalysis/Types/ArrayType.cs index c0a6765..5318441 100644 --- a/Crater/SemanticAnalysis/Types/ArrayType.cs +++ b/Crater/SemanticAnalysis/Types/ArrayType.cs @@ -16,7 +16,16 @@ public override bool CanHold(Type other) if (other is EmptyArrayType) return true; - return IsSameType(other); + if (other is not ArrayType otherArray) + return false; + + if (otherArray.ElementType is EmptyArrayType) + return true; + + if (ElementType is ArrayType selfElement && otherArray.ElementType is ArrayType otherElement) + return selfElement.CanHold(otherElement); + + return ElementType.IsSameType(otherArray.ElementType); } public override bool IsSameType(Type other) diff --git a/Tests/ArrayTypeTests.cs b/Tests/ArrayTypeTests.cs index 0db783f..9dbe3c7 100644 --- a/Tests/ArrayTypeTests.cs +++ b/Tests/ArrayTypeTests.cs @@ -58,4 +58,41 @@ public void CanIndexRecursiveArrays() Assert.That(innerResult, Is.Not.Null); Assert.That(innerResult.IsSameType(new NullableType(TypeRegistry.NumberType))); } + + [Test] + public void CanHoldNestedEmptyArray() + { + var numberArray = new ArrayType(TypeRegistry.NumberType, TypeRegistry.AnyType); + var nestedNumberArray = new ArrayType(numberArray, TypeRegistry.AnyType); + var nestedEmptyArray = new ArrayType(new EmptyArrayType(), TypeRegistry.AnyType); + + Assert.That(nestedNumberArray.CanHold(nestedEmptyArray)); + } + + [Test] + public void CanHoldDeeplyNestedEmptyArray() + { + var numberArray = new ArrayType(TypeRegistry.NumberType, TypeRegistry.AnyType); + var nestedNumberArray = new ArrayType(numberArray, TypeRegistry.AnyType); + var deeplyNestedNumberArray = new ArrayType(nestedNumberArray, TypeRegistry.AnyType); + + var emptyArray = new EmptyArrayType(); + var nestedEmptyArray = new ArrayType(emptyArray, TypeRegistry.AnyType); + var deeplyNestedEmptyArray = new ArrayType(nestedEmptyArray, TypeRegistry.AnyType); + + Assert.That(deeplyNestedNumberArray.CanHold(deeplyNestedEmptyArray)); + } + + [Test] + public void EmptyNestedArrayCannotHoldConcreteNestedArray() + { + var emptyArray = new EmptyArrayType(); + var nestedEmptyArray = new ArrayType(emptyArray, TypeRegistry.AnyType); + var emptyNestedArray = new ArrayType(nestedEmptyArray, TypeRegistry.AnyType); + + var numberArray = new ArrayType(TypeRegistry.NumberType, TypeRegistry.AnyType); + var nestedNumberArray = new ArrayType(numberArray, TypeRegistry.AnyType); + + Assert.That(!emptyNestedArray.CanHold(nestedNumberArray)); + } }