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;
}