mirror of https://github.com/golang/go.git
[dev.unified] cmd/compile: extract nil handling from exprType
Type switches are the only context where exprType was used and `nilOK` was true. It'll simplify subsequent dictionary work somewhat if exprType doesn't need to worry about `nil`, so extract this logic and move it into switchStmt instead. Change-Id: I3d810f465173f5bb2e2dee7bbc7843fff6a62ee5 Reviewed-on: https://go-review.googlesource.com/c/go/+/419474 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
92798176e7
commit
831fdf1dff
|
|
@ -1547,7 +1547,11 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node {
|
||||||
cases = nil // TODO(mdempsky): Unclear if this matters.
|
cases = nil // TODO(mdempsky): Unclear if this matters.
|
||||||
}
|
}
|
||||||
for i := range cases {
|
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 {
|
} else {
|
||||||
cases = r.exprList()
|
cases = r.exprList()
|
||||||
|
|
@ -1734,7 +1738,7 @@ func (r *reader) expr() (res ir.Node) {
|
||||||
case exprAssert:
|
case exprAssert:
|
||||||
x := r.expr()
|
x := r.expr()
|
||||||
pos := r.pos()
|
pos := r.pos()
|
||||||
typ := r.exprType(false)
|
typ := r.exprType()
|
||||||
srcRType := r.rtype(pos)
|
srcRType := r.rtype(pos)
|
||||||
|
|
||||||
// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
|
// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
|
||||||
|
|
@ -1800,7 +1804,7 @@ func (r *reader) expr() (res ir.Node) {
|
||||||
|
|
||||||
case exprMake:
|
case exprMake:
|
||||||
pos := r.pos()
|
pos := r.pos()
|
||||||
typ := r.exprType(false)
|
typ := r.exprType()
|
||||||
extra := r.exprs()
|
extra := r.exprs()
|
||||||
n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
|
n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
|
||||||
n.RType = r.rtype(pos)
|
n.RType = r.rtype(pos)
|
||||||
|
|
@ -1808,7 +1812,7 @@ func (r *reader) expr() (res ir.Node) {
|
||||||
|
|
||||||
case exprNew:
|
case exprNew:
|
||||||
pos := r.pos()
|
pos := r.pos()
|
||||||
typ := r.exprType(false)
|
typ := r.exprType()
|
||||||
return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
|
return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
|
||||||
|
|
||||||
case exprConvert:
|
case exprConvert:
|
||||||
|
|
@ -2043,13 +2047,9 @@ func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *reader) exprType(nilOK bool) ir.Node {
|
func (r *reader) exprType() ir.Node {
|
||||||
r.Sync(pkgbits.SyncExprType)
|
r.Sync(pkgbits.SyncExprType)
|
||||||
|
|
||||||
if nilOK && r.Bool() {
|
|
||||||
return typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := r.pos()
|
pos := r.pos()
|
||||||
setBasePos(pos)
|
setBasePos(pos)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1464,7 +1464,10 @@ func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
|
||||||
if iface != nil {
|
if iface != nil {
|
||||||
w.Len(len(cases))
|
w.Len(len(cases))
|
||||||
for _, cas := range cases {
|
for _, cas := range cases {
|
||||||
w.exprType(iface, cas, true)
|
if w.Bool(isNil(w.p.info, cas)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
w.exprType(iface, cas)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// As if w.exprList(clause.Cases),
|
// As if w.exprList(clause.Cases),
|
||||||
|
|
@ -1642,7 +1645,7 @@ func (w *writer) expr(expr syntax.Expr) {
|
||||||
w.Code(exprAssert)
|
w.Code(exprAssert)
|
||||||
w.expr(expr.X)
|
w.expr(expr.X)
|
||||||
w.pos(expr)
|
w.pos(expr)
|
||||||
w.exprType(iface, expr.Type, false)
|
w.exprType(iface, expr.Type)
|
||||||
w.rtype(iface)
|
w.rtype(iface)
|
||||||
|
|
||||||
case *syntax.Operation:
|
case *syntax.Operation:
|
||||||
|
|
@ -1702,7 +1705,7 @@ func (w *writer) expr(expr syntax.Expr) {
|
||||||
|
|
||||||
w.Code(exprMake)
|
w.Code(exprMake)
|
||||||
w.pos(expr)
|
w.pos(expr)
|
||||||
w.exprType(nil, expr.ArgList[0], false)
|
w.exprType(nil, expr.ArgList[0])
|
||||||
w.exprs(expr.ArgList[1:])
|
w.exprs(expr.ArgList[1:])
|
||||||
|
|
||||||
typ := w.p.typeOf(expr)
|
typ := w.p.typeOf(expr)
|
||||||
|
|
@ -1725,7 +1728,7 @@ func (w *writer) expr(expr syntax.Expr) {
|
||||||
|
|
||||||
w.Code(exprNew)
|
w.Code(exprNew)
|
||||||
w.pos(expr)
|
w.pos(expr)
|
||||||
w.exprType(nil, expr.ArgList[0], false)
|
w.exprType(nil, expr.ArgList[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
case "append":
|
case "append":
|
||||||
|
|
@ -1960,21 +1963,15 @@ func (w *writer) convRTTI(src, dst types2.Type) {
|
||||||
w.typ(dst)
|
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)
|
base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
|
||||||
|
|
||||||
tv, ok := w.p.info.Types[typ]
|
tv, ok := w.p.info.Types[typ]
|
||||||
assert(ok)
|
assert(ok)
|
||||||
|
|
||||||
w.Sync(pkgbits.SyncExprType)
|
|
||||||
|
|
||||||
if nilOK && w.Bool(tv.IsNil()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(tv.IsType())
|
assert(tv.IsType())
|
||||||
info := w.p.typIdx(tv.Type, w.dict)
|
info := w.p.typIdx(tv.Type, w.dict)
|
||||||
|
|
||||||
|
w.Sync(pkgbits.SyncExprType)
|
||||||
w.pos(typ)
|
w.pos(typ)
|
||||||
|
|
||||||
if w.Bool(info.derived && iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
|
if w.Bool(info.derived && iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
|
||||||
|
|
@ -2386,6 +2383,14 @@ func isMultiValueExpr(info *types2.Info, expr syntax.Expr) bool {
|
||||||
return false
|
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.
|
// recvBase returns the base type for the given receiver parameter.
|
||||||
func recvBase(recv *types2.Var) *types2.Named {
|
func recvBase(recv *types2.Var) *types2.Named {
|
||||||
typ := recv.Type()
|
typ := recv.Type()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue