1
0
mirror of https://github.com/golang/go synced 2024-11-17 10:34:49 -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 exprType // type expression
exprLocal // local variable exprLocal // local variable
exprGlobal // global variable or function exprGlobal // global variable or function
exprBlank
exprCompLit exprCompLit
exprFuncLit exprFuncLit
exprSelector exprSelector
@ -55,6 +54,17 @@ const (
exprConvert 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 type codeDecl int
func (c codeDecl) Marker() pkgbits.SyncMarker { return pkgbits.SyncDecl } func (c codeDecl) Marker() pkgbits.SyncMarker { return pkgbits.SyncDecl }

View File

@ -1323,25 +1323,41 @@ func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
var names []*ir.Name var names []*ir.Name
for i := range lhs { for i := range lhs {
if r.Bool() { expr, def := r.assign()
pos := r.pos() lhs[i] = expr
_, sym := r.localIdent() if def {
typ := r.typ() names = append(names, expr.(*ir.Name))
name := ir.NewNameAt(pos, sym)
lhs[i] = name
names = append(names, name)
setType(name, typ)
r.addLocal(name, ir.PAUTO)
continue
} }
lhs[i] = r.expr()
} }
return names, lhs 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)
setType(name, typ)
r.addLocal(name, ir.PAUTO)
return name, true
case assignExpr:
return r.expr(), false
}
}
func (r *reader) blockStmt() []ir.Node { func (r *reader) blockStmt() []ir.Node {
r.Sync(pkgbits.SyncBlockStmt) r.Sync(pkgbits.SyncBlockStmt)
r.openScope() r.openScope()
@ -1551,11 +1567,6 @@ func (r *reader) expr() (res ir.Node) {
default: default:
panic("unhandled expression") 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: case exprLocal:
return typecheck.Expr(r.useLocal()) return typecheck.Expr(r.useLocal())

View File

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

View File

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

View File

@ -45,39 +45,40 @@ func _() {
_ = x[SyncExprs-35] _ = x[SyncExprs-35]
_ = x[SyncExpr-36] _ = x[SyncExpr-36]
_ = x[SyncExprType-37] _ = x[SyncExprType-37]
_ = x[SyncOp-38] _ = x[SyncAssign-38]
_ = x[SyncFuncLit-39] _ = x[SyncOp-39]
_ = x[SyncCompLit-40] _ = x[SyncFuncLit-40]
_ = x[SyncDecl-41] _ = x[SyncCompLit-41]
_ = x[SyncFuncBody-42] _ = x[SyncDecl-42]
_ = x[SyncOpenScope-43] _ = x[SyncFuncBody-43]
_ = x[SyncCloseScope-44] _ = x[SyncOpenScope-44]
_ = x[SyncCloseAnotherScope-45] _ = x[SyncCloseScope-45]
_ = x[SyncDeclNames-46] _ = x[SyncCloseAnotherScope-46]
_ = x[SyncDeclName-47] _ = x[SyncDeclNames-47]
_ = x[SyncStmts-48] _ = x[SyncDeclName-48]
_ = x[SyncBlockStmt-49] _ = x[SyncStmts-49]
_ = x[SyncIfStmt-50] _ = x[SyncBlockStmt-50]
_ = x[SyncForStmt-51] _ = x[SyncIfStmt-51]
_ = x[SyncSwitchStmt-52] _ = x[SyncForStmt-52]
_ = x[SyncRangeStmt-53] _ = x[SyncSwitchStmt-53]
_ = x[SyncCaseClause-54] _ = x[SyncRangeStmt-54]
_ = x[SyncCommClause-55] _ = x[SyncCaseClause-55]
_ = x[SyncSelectStmt-56] _ = x[SyncCommClause-56]
_ = x[SyncDecls-57] _ = x[SyncSelectStmt-57]
_ = x[SyncLabeledStmt-58] _ = x[SyncDecls-58]
_ = x[SyncUseObjLocal-59] _ = x[SyncLabeledStmt-59]
_ = x[SyncAddLocal-60] _ = x[SyncUseObjLocal-60]
_ = x[SyncLinkname-61] _ = x[SyncAddLocal-61]
_ = x[SyncStmt1-62] _ = x[SyncLinkname-62]
_ = x[SyncStmtsEnd-63] _ = x[SyncStmt1-63]
_ = x[SyncLabel-64] _ = x[SyncStmtsEnd-64]
_ = x[SyncOptLabel-65] _ = 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 { func (i SyncMarker) String() string {
i -= 1 i -= 1