private TypeSymbol? NarrowArrayAssignmentType()

in src/Bicep.Core/TypeSystem/TypeValidator.cs [600:673]


        private TypeSymbol? NarrowArrayAssignmentType(TypeValidatorConfig config, SyntaxBase expression, TypeSymbol expressionType, ArrayType targetType)
        {
            switch (expression)
            {
                case ArraySyntax arrayValue:
                    return NarrowArrayAssignmentType(config, arrayValue, targetType);
                case VariableAccessSyntax variableAccess when DeclaringSyntax(variableAccess) is SyntaxBase declaringSyntax:
                    var newConfig = config with { OriginSyntax = variableAccess };
                    return NarrowType(newConfig, declaringSyntax, targetType);
            }

            if (expressionType is TupleType expressionTuple && targetType is TupleType targetTuple)
            {
                if (expressionTuple.Items.Length != targetTuple.Items.Length)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceHigh(
                        config.IsResourceDeclaration || ShouldWarn(targetType),
                        expressionTuple.Items.Length,
                        targetTuple.Items.Length));
                    return expressionType;
                }

                return new TupleType(validationFlags: targetTuple.ValidationFlags,
                    items: Enumerable.Range(0, expressionTuple.Items.Length)
                        .Select(idx => NarrowType(config, expression, expressionTuple.Items[idx].Type, targetTuple.Items[idx].Type))
                        .ToImmutableArray<ITypeReference>());
            }

            if (expressionType is ArrayType expressionArrayType)
            {
                if (expressionArrayType.MinLength.HasValue && targetType.MaxLength.HasValue && expressionArrayType.MinLength.Value > targetType.MaxLength.Value)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceHigh(
                        config.IsResourceDeclaration || ShouldWarn(targetType),
                        expressionArrayType.MinLength.Value,
                        targetType.MaxLength.Value));
                    return expressionType;
                }

                if (expressionArrayType.MaxLength.HasValue && targetType.MinLength.HasValue && expressionArrayType.MaxLength.Value < targetType.MinLength.Value)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceLow(
                        config.IsResourceDeclaration || ShouldWarn(targetType),
                        expressionArrayType.MaxLength.Value,
                        targetType.MinLength.Value));
                    return expressionType;
                }

                if (expressionArrayType.MinLength.HasValue && targetType.MinLength.HasValue && expressionArrayType.MinLength.Value < targetType.MinLength.Value)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainExtendsBelowTargetValueLengthDomain(expressionArrayType.MinLength.Value, targetType.MinLength.Value));
                }

                if (expressionArrayType.MaxLength.HasValue && targetType.MaxLength.HasValue && expressionArrayType.MaxLength.Value > targetType.MaxLength.Value)
                {
                    diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainExtendsAboveTargetValueLengthDomain(expressionArrayType.MaxLength.Value, targetType.MaxLength.Value));
                }

                return new TypedArrayType(NarrowType(config, expression, expressionArrayType.Item.Type, targetType.Item.Type),
                    targetType.ValidationFlags,
                    minLength: Math.Max(expressionArrayType.MinLength ?? 0, targetType.MinLength ?? 0) switch
                    {
                        <= 0 => null,
                        long otherwise => otherwise,
                    },
                    maxLength: Math.Min(expressionArrayType.MaxLength ?? long.MaxValue, targetType.MaxLength ?? long.MaxValue) switch
                    {
                        long.MaxValue => null,
                        long otherwise => otherwise,
                    });
            }

            return null;
        }