cases = nil // TODO(mdempsky): Unclear if this matters.
}
for i := range cases {
- cases[i] = r.exprType(true)
+ if r.Bool() { // case nil
+ cases[i] = typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
+ } else {
+ cases[i] = r.exprType()
+ }
}
} else {
cases = r.exprList()
case exprAssert:
x := r.expr()
pos := r.pos()
- typ := r.exprType(false)
+ typ := r.exprType()
srcRType := r.rtype(pos)
// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
case exprMake:
pos := r.pos()
- typ := r.exprType(false)
+ typ := r.exprType()
extra := r.exprs()
n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
n.RType = r.rtype(pos)
case exprNew:
pos := r.pos()
- typ := r.exprType(false)
+ typ := r.exprType()
return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
case exprConvert:
return
}
-func (r *reader) exprType(nilOK bool) ir.Node {
+func (r *reader) exprType() ir.Node {
r.Sync(pkgbits.SyncExprType)
- if nilOK && r.Bool() {
- return typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
- }
-
pos := r.pos()
setBasePos(pos)
if iface != nil {
w.Len(len(cases))
for _, cas := range cases {
- w.exprType(iface, cas, true)
+ if w.Bool(isNil(w.p.info, cas)) {
+ continue
+ }
+ w.exprType(iface, cas)
}
} else {
// As if w.exprList(clause.Cases),
w.Code(exprAssert)
w.expr(expr.X)
w.pos(expr)
- w.exprType(iface, expr.Type, false)
+ w.exprType(iface, expr.Type)
w.rtype(iface)
case *syntax.Operation:
w.Code(exprMake)
w.pos(expr)
- w.exprType(nil, expr.ArgList[0], false)
+ w.exprType(nil, expr.ArgList[0])
w.exprs(expr.ArgList[1:])
typ := w.p.typeOf(expr)
w.Code(exprNew)
w.pos(expr)
- w.exprType(nil, expr.ArgList[0], false)
+ w.exprType(nil, expr.ArgList[0])
return
case "append":
w.typ(dst)
}
-func (w *writer) exprType(iface types2.Type, typ syntax.Expr, nilOK bool) {
+func (w *writer) exprType(iface types2.Type, typ syntax.Expr) {
base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
tv, ok := w.p.info.Types[typ]
assert(ok)
-
- w.Sync(pkgbits.SyncExprType)
-
- if nilOK && w.Bool(tv.IsNil()) {
- return
- }
-
assert(tv.IsType())
info := w.p.typIdx(tv.Type, w.dict)
+ w.Sync(pkgbits.SyncExprType)
w.pos(typ)
if w.Bool(info.derived && iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
return false
}
+// isNil reports whether expr is a (possibly parenthesized) reference
+// to the predeclared nil value.
+func isNil(info *types2.Info, expr syntax.Expr) bool {
+ tv, ok := info.Types[expr]
+ assert(ok)
+ return tv.IsNil()
+}
+
// recvBase returns the base type for the given receiver parameter.
func recvBase(recv *types2.Var) *types2.Named {
typ := recv.Type()