Skip to content

Commit

Permalink
Report invalid types in least-common-supertype calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
SupunS committed Jul 25, 2024
1 parent af5f75d commit 6fa876b
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 23 deletions.
10 changes: 1 addition & 9 deletions runtime/sema/check_array_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,8 @@ func (checker *Checker) VisitArrayExpression(arrayExpression *ast.ArrayExpressio
if elementType == nil {
// Contextually expected type is not available.
// Therefore, find the least common supertype of the elements.
elementType = LeastCommonSuperType(argumentTypes...)

elementType = checker.leastCommonSuperType(arrayExpression, argumentTypes...)
if elementType == InvalidType {
checker.report(
&TypeAnnotationRequiredError{
Cause: "cannot infer type from array literal:",
Pos: arrayExpression.StartPos,
},
)

return InvalidType
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/sema/check_binary_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,5 +468,5 @@ func (checker *Checker) checkBinaryExpressionNilCoalescing(
}
}

return LeastCommonSuperType(leftOptional.Type, rightType)
return checker.leastCommonSuperType(expression, leftOptional.Type, rightType)
}
2 changes: 1 addition & 1 deletion runtime/sema/check_conditional.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (checker *Checker) VisitConditionalExpression(expression *ast.ConditionalEx
return thenType
}

return LeastCommonSuperType(thenType, elseType)
return checker.leastCommonSuperType(expression, thenType, elseType)
}

// checkConditionalBranches checks two conditional branches.
Expand Down
17 changes: 6 additions & 11 deletions runtime/sema/check_dictionary_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,13 @@ func (checker *Checker) VisitDictionaryExpression(expression *ast.DictionaryExpr
if keyType == nil && valueType == nil {
// Contextually expected type is not available.
// Therefore, find the least common supertype of the keys and values.
keyType = LeastCommonSuperType(keyTypes...)
valueType = LeastCommonSuperType(valueTypes...)

if keyType == InvalidType ||
valueType == InvalidType {
checker.report(
&TypeAnnotationRequiredError{
Cause: "cannot infer type from dictionary literal:",
Pos: expression.StartPos,
},
)
keyType = checker.leastCommonSuperType(expression, keyTypes...)
if keyType == InvalidType {
return InvalidType
}

valueType = checker.leastCommonSuperType(expression, valueTypes...)
if valueType == InvalidType {
return InvalidType
}
}
Expand Down
15 changes: 15 additions & 0 deletions runtime/sema/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2766,3 +2766,18 @@ func (checker *Checker) checkNativeModifier(isNative bool, position ast.HasPosit
)
}
}

func (checker *Checker) leastCommonSuperType(pos ast.HasPosition, types ...Type) Type {
elementType := LeastCommonSuperType(types...)

if elementType == InvalidType {
checker.report(
&TypeAnnotationRequiredError{
Cause: "cannot infer type:",
Pos: pos.StartPosition(),
},
)
}

return elementType
}
3 changes: 2 additions & 1 deletion runtime/tests/checker/conditional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ func TestCheckInvalidConditionalExpressionElse(t *testing.T) {
let x = true ? 2 : y
`)

errs := RequireCheckerErrors(t, err, 1)
errs := RequireCheckerErrors(t, err, 2)

assert.IsType(t, &sema.NotDeclaredError{}, errs[0])
assert.IsType(t, &sema.TypeAnnotationRequiredError{}, errs[1])

xType := RequireGlobalValue(t, checker.Elaboration, "x")
assert.Equal(t, sema.InvalidType, xType)
Expand Down

0 comments on commit 6fa876b

Please sign in to comment.