(typ super.Type, e sem.Expr)
| 275 | } |
| 276 | |
| 277 | func (c *checker) expr(typ super.Type, e sem.Expr) super.Type { |
| 278 | //XXX for now, just deref any super types. A project is to make |
| 279 | // a mixed-static/super type checker that understands supers |
| 280 | // are summary types and regular types are exact types. |
| 281 | // question is to make mixed-type branches (e.g., case branches) |
| 282 | // a super or a union. Latter would impact the design of type-safety |
| 283 | // semantics of dereferencing such values and should case allow None? |
| 284 | typ = defuse(typ) |
| 285 | switch e := e.(type) { |
| 286 | case nil: |
| 287 | return c.unknown |
| 288 | case *sem.AggFunc: |
| 289 | c.expr(typ, e.Expr) |
| 290 | c.expr(typ, e.Filter) |
| 291 | // XXX This will be handled in a subsequent PR where we add type signatures |
| 292 | // to the package containing the agg func implementatons. |
| 293 | return c.unknown |
| 294 | case *sem.AggRef: |
| 295 | // AggRef's should never appear here but they can show up when |
| 296 | // we are traversing the demand exprs in a SQL SELECT where we |
| 297 | // do not care about type checking (because ORDER BY will re-do |
| 298 | // the type checks with the output scope available). |
| 299 | return c.unknown |
| 300 | case *sem.ArrayExpr: |
| 301 | return c.t.sctx.LookupTypeArray(c.arrayElems(typ, e.Elems)) |
| 302 | case *sem.BadExpr: |
| 303 | return c.unknown |
| 304 | case *sem.BinaryExpr: |
| 305 | lhs := c.expr(typ, e.LHS) |
| 306 | rhs := c.expr(typ, e.RHS) |
| 307 | return c.binary(e.Op, e, e.LHS, e.RHS, lhs, rhs) |
| 308 | case *sem.CallExpr: |
| 309 | var types []super.Type |
| 310 | for _, e := range e.Args { |
| 311 | types = append(types, c.expr(typ, e)) |
| 312 | } |
| 313 | if isBuiltin(e.Tag) { |
| 314 | return c.callBuiltin(e, types) |
| 315 | } |
| 316 | return c.callFunc(e, types) |
| 317 | case *sem.CondExpr: |
| 318 | c.boolean(e.Cond, c.expr(typ, e.Cond)) |
| 319 | c.pushErrs() |
| 320 | thenType := c.expr(typ, e.Then) |
| 321 | thenErrs := c.popErrs() |
| 322 | c.pushErrs() |
| 323 | elseType := c.expr(typ, e.Else) |
| 324 | elseErrs := c.popErrs() |
| 325 | if len(thenErrs) != 0 && len(elseErrs) != 0 { |
| 326 | c.error(thenErrs[0].loc, fmt.Errorf("no valid conditional branch found: %w", thenErrs[0].err)) |
| 327 | c.error(elseErrs[0].loc, fmt.Errorf("no valid conditional branch found: %w", elseErrs[0].err)) |
| 328 | } |
| 329 | return c.fuse([]super.Type{thenType, elseType}) |
| 330 | case *sem.DotExpr: |
| 331 | typ, _ := c.deref(e.Node, c.expr(typ, e.LHS), e.RHS) |
| 332 | return typ |
| 333 | case *sem.IndexExpr: |
| 334 | typ, _ := c.indexOf(e.Expr, e.Index, c.expr(typ, e.Expr), c.expr(typ, e.Index)) |
no test coverage detected