Skip to content

Commit 282244d

Browse files
committed
Improve type checker
1 parent 87534e6 commit 282244d

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

checker/checker.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,22 @@ func (v *visitor) BinaryNode(node *ast.BinaryNode) (reflect.Type, info) {
275275
return anyType, info{}
276276
}
277277

278-
case "/", "*":
278+
case "*":
279279
if isNumber(l) && isNumber(r) {
280280
return combined(l, r), info{}
281281
}
282282
if or(l, r, isNumber) {
283283
return anyType, info{}
284284
}
285285

286+
case "/":
287+
if isNumber(l) && isNumber(r) {
288+
return floatType, info{}
289+
}
290+
if or(l, r, isNumber) {
291+
return floatType, info{}
292+
}
293+
286294
case "**", "^":
287295
if isNumber(l) && isNumber(r) {
288296
return floatType, info{}
@@ -321,15 +329,21 @@ func (v *visitor) BinaryNode(node *ast.BinaryNode) (reflect.Type, info) {
321329
return boolType, info{}
322330
}
323331
if isMap(r) {
324-
if l == nil {
325-
return v.error(node, "cannot use nil as map key")
332+
if l == nil { // It is possible to compare with nil.
333+
return boolType, info{}
326334
}
327335
if !isAny(l) && !l.AssignableTo(r.Key()) {
328-
return v.error(node, "cannot use %v (type %v) as type %v in map key", l, l, r.Key())
336+
return v.error(node, "cannot use %v as type %v in map key", l, r.Key())
329337
}
330338
return boolType, info{}
331339
}
332-
if isInteger(l) && isArray(r) {
340+
if isArray(r) {
341+
if l == nil { // It is possible to compare with nil.
342+
return boolType, info{}
343+
}
344+
if !isAny(l) && !isInteger(l) {
345+
return v.error(node, "cannot use %v as type %v in array", l, r.Elem())
346+
}
333347
return boolType, info{}
334348
}
335349
if isAny(l) && anyOf(r, isString, isArray, isMap) {

checker/checker_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ var successTests = []string{
5555
"(Any ? 0 : nil) == 0",
5656
"(Any ? nil : nil) == nil",
5757
"!(Any ? Foo : Foo.Bar).Anything",
58-
"String in ArrayOfFoo",
58+
"Int in ArrayOfFoo",
59+
"Int not in ArrayOfFoo",
5960
"String in Foo",
6061
"String in MapOfFoo",
6162
"String matches 'ok'",
6263
"String matches Any",
6364
"String not matches Any",
64-
"String not in ArrayOfFoo",
6565
"StringPtr == nil",
6666
"[1, 2, 3] == []",
6767
"len([]) > 0",
@@ -491,9 +491,14 @@ cannot use int as argument (type string) to call FuncTyped (1:11)
491491
| ..........^
492492
493493
.0 in MapOfFoo
494-
cannot use float64 (type float64) as type string in map key (1:4)
494+
cannot use float64 as type string in map key (1:4)
495495
| .0 in MapOfFoo
496496
| ...^
497+
498+
1/2 in MapIntAny
499+
cannot use float64 as type int in map key (1:5)
500+
| 1/2 in MapIntAny
501+
| ....^
497502
`
498503

499504
func TestCheck_error(t *testing.T) {

0 commit comments

Comments
 (0)