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

Use target rather than expression type as narrowing base case #15398

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/Bicep.Core.IntegrationTests/ScenarioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6258,4 +6258,39 @@ public void Recursive_types_generate_diagnostics_where_referenced()
("BCP062", DiagnosticLevel.Error, """The referenced declaration with name "invalidRecursiveObjectType" is not valid."""),
]);
}

// https://github.com/Azure/bicep/issues/15114
[TestMethod]
public void Test_Issue15114()
{
var result = CompilationHelper.Compile("""
param recoverDeleted bool

resource KeyVaultResource 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: 'vault'
location: resourceGroup().location
properties: recoverDeleted
? {
createMode: 'recover'
sku: {
name: 'standard'
family: 'A'
}
tenantId: tenant().tenantId
}
: {
createMode: 'default'
sku: {
name: 'standard'
family: 'A'
}
tenantId: tenant().tenantId
}
}

output keyvaultUri string = KeyVaultResource.properties.vaultUri
""");

result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ func objReturnType(name string) object => {

func arrayReturnType(name string) array => [
//@[21:025) Local name. Type: string. Declaration start char: 21, length: 11
//@[05:020) Function arrayReturnType. Type: string => [string]. Declaration start char: 0, length: 53
//@[05:020) Function arrayReturnType. Type: string => [any]. Declaration start char: 0, length: 53
name
]

func asdf(name string) array => [
//@[10:014) Local name. Type: string. Declaration start char: 10, length: 11
//@[05:009) Function asdf. Type: string => ['asdf', string]. Declaration start char: 0, length: 51
//@[05:009) Function asdf. Type: string => [any, any]. Declaration start char: 0, length: 51
'asdf'
name
]
Expand All @@ -43,10 +43,10 @@ func typedArg(input string[]) positiveInt => length(input)
//@[05:013) Function typedArg. Type: string[] => int. Declaration start char: 0, length: 58

func barTest() array => ['abc', 'def']
//@[05:012) Function barTest. Type: () => ['abc', 'def']. Declaration start char: 0, length: 38
//@[05:012) Function barTest. Type: () => [any, any]. Declaration start char: 0, length: 38
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the return types of these functions be array as well?

func fooTest() array => map(barTest(), a => 'Hello ${a}!')
//@[39:040) Local a. Type: any. Declaration start char: 39, length: 1
//@[05:012) Function fooTest. Type: () => string[]. Declaration start char: 0, length: 58
//@[05:012) Function fooTest. Type: () => array. Declaration start char: 0, length: 58

output fooValue array = fooTest()
//@[07:015) Output fooValue. Type: array. Declaration start char: 0, length: 33
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
func useRuntimeFunction() string => reference('foo').bar
//@[05:23) Function useRuntimeFunction. Type: () => any. Declaration start char: 0, length: 56
//@[05:23) Function useRuntimeFunction. Type: () => string. Declaration start char: 0, length: 56

func missingArgType(input) string => input
//@[20:25) Local input. Type: any. Declaration start char: 20, length: 5
//@[05:19) Function missingArgType. Type: any => any. Declaration start char: 0, length: 42
//@[05:19) Function missingArgType. Type: any => string. Declaration start char: 0, length: 42

func missingOutputType(input string) => input
//@[23:28) Local input. Type: string. Declaration start char: 23, length: 12
Expand Down Expand Up @@ -35,7 +35,7 @@ func argLengthMismatch(a string, b string, c string) array => ([a, b, c])
//@[23:24) Local a. Type: string. Declaration start char: 23, length: 8
//@[33:34) Local b. Type: string. Declaration start char: 33, length: 8
//@[43:44) Local c. Type: string. Declaration start char: 43, length: 8
//@[05:22) Function argLengthMismatch. Type: (string, string, string) => string[]. Declaration start char: 0, length: 73
//@[05:22) Function argLengthMismatch. Type: (string, string, string) => array. Declaration start char: 0, length: 73
var sdf = argLengthMismatch('asdf')
//@[04:07) Variable sdf. Type: error. Declaration start char: 0, length: 35

Expand All @@ -58,7 +58,7 @@ type validStringLiteralUnion = 'foo'|'bar'|'baz'
func invalidArgs(a validStringLiteralUnion, b string) string => a
//@[17:18) Local a. Type: 'bar' | 'baz' | 'foo'. Declaration start char: 17, length: 25
//@[44:45) Local b. Type: string. Declaration start char: 44, length: 8
//@[05:16) Function invalidArgs. Type: (('bar' | 'baz' | 'foo'), string) => ('bar' | 'baz' | 'foo'). Declaration start char: 0, length: 65
//@[05:16) Function invalidArgs. Type: (('bar' | 'baz' | 'foo'), string) => string. Declaration start char: 0, length: 65
func invalidOutput() validStringLiteralUnion => 'foo'
//@[05:18) Function invalidOutput. Type: () => 'foo'. Declaration start char: 0, length: 53

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,11 @@ static object[] Row(TypeSymbol sourceType, TypeSymbol targetType, TypeSymbol exp
// A source type whose domain is disjoint from the domain of the target should error and not narrow
Row(TypeFactory.CreateStringType(minLength: 10),
TypeFactory.CreateStringType(maxLength: 9),
TypeFactory.CreateStringType(minLength: 10),
TypeFactory.CreateStringType(maxLength: 9),
("BCP332", DiagnosticLevel.Error, "The provided value (whose length will always be greater than or equal to 10) is too long to assign to a target for which the maximum allowable length is 9.")),
Row(TypeFactory.CreateStringType(maxLength: 9),
TypeFactory.CreateStringType(minLength: 10),
TypeFactory.CreateStringType(maxLength: 9),
TypeFactory.CreateStringType(minLength: 10),
("BCP333", DiagnosticLevel.Error, "The provided value (whose length will always be less than or equal to 9) is too short to assign to a target for which the minimum allowable length is 10.")),
Row(TypeFactory.CreateStringLiteralType("0123456789"),
TypeFactory.CreateStringType(maxLength: 9),
Expand Down Expand Up @@ -369,19 +369,19 @@ static object[] Row(TypeSymbol sourceType, TypeSymbol targetType, TypeSymbol exp
// A source type whose domain is disjoint from the domain of the target should error and not narrow
Row(TypeFactory.CreateIntegerType(minValue: 10),
TypeFactory.CreateIntegerType(maxValue: 9),
TypeFactory.CreateIntegerType(minValue: 10),
TypeFactory.CreateIntegerType(maxValue: 9),
("BCP327", DiagnosticLevel.Error, "The provided value (which will always be greater than or equal to 10) is too large to assign to a target for which the maximum allowable value is 9.")),
Row(TypeFactory.CreateIntegerType(maxValue: 9),
TypeFactory.CreateIntegerType(minValue: 10),
TypeFactory.CreateIntegerType(maxValue: 9),
TypeFactory.CreateIntegerType(minValue: 10),
("BCP328", DiagnosticLevel.Error, "The provided value (which will always be less than or equal to 9) is too small to assign to a target for which the minimum allowable value is 10.")),
Row(TypeFactory.CreateIntegerLiteralType(10),
TypeFactory.CreateIntegerType(maxValue: 9),
TypeFactory.CreateIntegerLiteralType(10),
TypeFactory.CreateIntegerType(maxValue: 9),
("BCP327", DiagnosticLevel.Error, "The provided value (which will always be greater than or equal to 10) is too large to assign to a target for which the maximum allowable value is 9.")),
Row(TypeFactory.CreateIntegerLiteralType(9),
TypeFactory.CreateIntegerType(minValue: 10),
TypeFactory.CreateIntegerLiteralType(9),
TypeFactory.CreateIntegerType(minValue: 10),
("BCP328", DiagnosticLevel.Error, "The provided value (which will always be less than or equal to 9) is too small to assign to a target for which the minimum allowable value is 10.")),
Row(TypeFactory.CreateIntegerType(minValue: 10, validationFlags: TypeSymbolValidationFlags.AllowLooseAssignment),
TypeFactory.CreateIntegerLiteralType(9),
Expand Down
8 changes: 4 additions & 4 deletions src/Bicep.Core/TypeSystem/TypeValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ private TypeSymbol NarrowType(TypeValidatorConfig config, SyntaxBase expression,
return NarrowLambdaType(config, sourceLambda, targetLambdaType);
}

return expressionType;
return targetType;
}

private static SyntaxBase UnwrapIfConditionBody(SyntaxBase expression) => expression switch
Expand Down Expand Up @@ -457,7 +457,7 @@ private TypeSymbol NarrowIntegerAssignmentType(TypeValidatorConfig config, Synta
return expressionIntegerLiteral;
}

return expressionType;
return targetType;
}

private TypeSymbol NarrowIntegerLiteralAssignmentType(TypeValidatorConfig config, SyntaxBase expression, TypeSymbol expressionType, IntegerLiteralType targetType)
Expand Down Expand Up @@ -548,7 +548,7 @@ private TypeSymbol NarrowStringAssignmentType(TypeValidatorConfig config, Syntax
return expressionStringLiteral;
}

return expressionType;
return targetType;
}

private TypeSymbol NarrowStringLiteralAssignmentType(TypeValidatorConfig config, SyntaxBase expression, TypeSymbol expressionType, StringLiteralType targetType)
Expand Down Expand Up @@ -1049,7 +1049,7 @@ static TypeSymbol RemoveImplicitNull(TypeSymbol type, bool typeWasPreserved)
// we should not return the parse errors however because they will get double collected
if (this.parsingErrorLookup.Contains(expression))
{
return targetType;
return null;
}

if (expressionType is ObjectType expressionObjectType)
Expand Down
Loading