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:
parent
55fc07e164
commit
b39ac80871
@ -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 }
|
||||||
|
@ -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())
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -90,6 +90,7 @@ const (
|
|||||||
SyncExprs
|
SyncExprs
|
||||||
SyncExpr
|
SyncExpr
|
||||||
SyncExprType
|
SyncExprType
|
||||||
|
SyncAssign
|
||||||
SyncOp
|
SyncOp
|
||||||
SyncFuncLit
|
SyncFuncLit
|
||||||
SyncCompLit
|
SyncCompLit
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user