1
0
mirror of https://github.com/golang/go synced 2024-11-05 16:06:10 -07:00

[dev.unified] cmd/compile/internal/noder: push exprBlank up into assignment handling

Blanks can only appear on the LHS of an assignment. Instead of
handling them as an arbitrary expression, handle them as part of
assignee expression lists.

Change-Id: Iaeb0a5c471ffa1abd2bbbd9c95f7876533e5a607
Reviewed-on: https://go-review.googlesource.com/c/go/+/410100
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2022-06-03 13:21:09 -07:00
parent 55fc07e164
commit b39ac80871
5 changed files with 97 additions and 67 deletions

View File

@ -42,7 +42,6 @@ const (
exprType // type expression
exprLocal // local variable
exprGlobal // global variable or function
exprBlank
exprCompLit
exprFuncLit
exprSelector
@ -55,6 +54,17 @@ const (
exprConvert
)
type codeAssign int
func (c codeAssign) Marker() pkgbits.SyncMarker { return pkgbits.SyncAssign }
func (c codeAssign) Value() int { return int(c) }
const (
assignBlank codeAssign = iota
assignDef
assignExpr
)
type codeDecl int
func (c codeDecl) Marker() pkgbits.SyncMarker { return pkgbits.SyncDecl }

View File

@ -1323,23 +1323,39 @@ func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
var names []*ir.Name
for i := range lhs {
if r.Bool() {
expr, def := r.assign()
lhs[i] = expr
if def {
names = append(names, expr.(*ir.Name))
}
}
return names, lhs
}
// assign returns an assignee expression. It also reports whether the
// returned expression is a newly declared variable.
func (r *reader) assign() (ir.Node, bool) {
switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
default:
panic("unhandled assignee expression")
case assignBlank:
return typecheck.AssignExpr(ir.BlankNode), false
case assignDef:
pos := r.pos()
_, sym := r.localIdent()
typ := r.typ()
name := ir.NewNameAt(pos, sym)
lhs[i] = name
names = append(names, name)
setType(name, typ)
r.addLocal(name, ir.PAUTO)
continue
}
return name, true
lhs[i] = r.expr()
case assignExpr:
return r.expr(), false
}
return names, lhs
}
func (r *reader) blockStmt() []ir.Node {
@ -1551,11 +1567,6 @@ func (r *reader) expr() (res ir.Node) {
default:
panic("unhandled expression")
case exprBlank:
// blank only allowed in LHS of assignments
// TODO(mdempsky): Handle directly in assignList instead?
return typecheck.AssignExpr(ir.BlankNode)
case exprLocal:
return typecheck.Expr(r.useLocal())

View File

@ -1023,11 +1023,23 @@ func (w *writer) assignList(expr syntax.Expr) {
w.Len(len(exprs))
for _, expr := range exprs {
if name, ok := expr.(*syntax.Name); ok && name.Value != "_" {
w.assign(expr)
}
}
func (w *writer) assign(expr syntax.Expr) {
expr = unparen(expr)
if name, ok := expr.(*syntax.Name); ok {
if name.Value == "_" {
w.Code(assignBlank)
return
}
if obj, ok := w.p.info.Defs[name]; ok {
obj := obj.(*types2.Var)
w.Bool(true)
w.Code(assignDef)
w.pos(obj)
w.localIdent(obj)
w.typ(obj.Type())
@ -1035,13 +1047,12 @@ func (w *writer) assignList(expr syntax.Expr) {
// TODO(mdempsky): Minimize locals index size by deferring
// this until the variables actually come into scope.
w.addLocal(obj)
continue
return
}
}
w.Bool(false)
w.Code(assignExpr)
w.expr(expr)
}
}
func (w *writer) declStmt(decl syntax.Decl) {
@ -1256,10 +1267,6 @@ func (w *writer) expr(expr syntax.Expr) {
default:
w.p.unexpected("expression", expr)
case *syntax.Name:
assert(expr.Value == "_")
w.Code(exprBlank)
case *syntax.CompositeLit:
w.Code(exprCompLit)
w.compLit(expr)

View File

@ -90,6 +90,7 @@ const (
SyncExprs
SyncExpr
SyncExprType
SyncAssign
SyncOp
SyncFuncLit
SyncCompLit

View File

@ -45,39 +45,40 @@ func _() {
_ = x[SyncExprs-35]
_ = x[SyncExpr-36]
_ = x[SyncExprType-37]
_ = x[SyncOp-38]
_ = x[SyncFuncLit-39]
_ = x[SyncCompLit-40]
_ = x[SyncDecl-41]
_ = x[SyncFuncBody-42]
_ = x[SyncOpenScope-43]
_ = x[SyncCloseScope-44]
_ = x[SyncCloseAnotherScope-45]
_ = x[SyncDeclNames-46]
_ = x[SyncDeclName-47]
_ = x[SyncStmts-48]
_ = x[SyncBlockStmt-49]
_ = x[SyncIfStmt-50]
_ = x[SyncForStmt-51]
_ = x[SyncSwitchStmt-52]
_ = x[SyncRangeStmt-53]
_ = x[SyncCaseClause-54]
_ = x[SyncCommClause-55]
_ = x[SyncSelectStmt-56]
_ = x[SyncDecls-57]
_ = x[SyncLabeledStmt-58]
_ = x[SyncUseObjLocal-59]
_ = x[SyncAddLocal-60]
_ = x[SyncLinkname-61]
_ = x[SyncStmt1-62]
_ = x[SyncStmtsEnd-63]
_ = x[SyncLabel-64]
_ = x[SyncOptLabel-65]
_ = x[SyncAssign-38]
_ = x[SyncOp-39]
_ = x[SyncFuncLit-40]
_ = x[SyncCompLit-41]
_ = x[SyncDecl-42]
_ = x[SyncFuncBody-43]
_ = x[SyncOpenScope-44]
_ = x[SyncCloseScope-45]
_ = x[SyncCloseAnotherScope-46]
_ = x[SyncDeclNames-47]
_ = x[SyncDeclName-48]
_ = x[SyncStmts-49]
_ = x[SyncBlockStmt-50]
_ = x[SyncIfStmt-51]
_ = x[SyncForStmt-52]
_ = x[SyncSwitchStmt-53]
_ = x[SyncRangeStmt-54]
_ = x[SyncCaseClause-55]
_ = x[SyncCommClause-56]
_ = x[SyncSelectStmt-57]
_ = x[SyncDecls-58]
_ = x[SyncLabeledStmt-59]
_ = x[SyncUseObjLocal-60]
_ = x[SyncAddLocal-61]
_ = x[SyncLinkname-62]
_ = x[SyncStmt1-63]
_ = x[SyncStmtsEnd-64]
_ = x[SyncLabel-65]
_ = x[SyncOptLabel-66]
}
const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprAssertTypeOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 228, 230, 237, 244, 248, 256, 265, 275, 292, 301, 309, 314, 323, 329, 336, 346, 355, 365, 375, 385, 390, 401, 412, 420, 428, 433, 441, 446, 454}
var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
func (i SyncMarker) String() string {
i -= 1