1
0
mirror of https://github.com/golang/go synced 2024-11-13 16:50:23 -07:00

cmd/compile: simplify {defer,resume}checkwidth logic

This CL extends {defer,resume}checkwidth to support nesting, which
simplifies usage.

Updates #33658.

Change-Id: Ib3ffb8a7cabfae2cbeba74e21748c228436f4726
Reviewed-on: https://go-review.googlesource.com/c/go/+/192721
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Matthew Dempsky 2019-08-30 14:54:21 -07:00
parent adf20ee3c5
commit 380ef6b759
6 changed files with 19 additions and 48 deletions

View File

@ -217,7 +217,7 @@ func dowidth(t *types.Type) {
} }
// defer checkwidth calls until after we're done // defer checkwidth calls until after we're done
defercalc++ defercheckwidth()
lno := lineno lno := lineno
if asNode(t.Nod) != nil { if asNode(t.Nod) != nil {
@ -391,11 +391,7 @@ func dowidth(t *types.Type) {
lineno = lno lineno = lno
if defercalc == 1 {
resumecheckwidth() resumecheckwidth()
} else {
defercalc--
}
} }
// when a type's width should be known, we call checkwidth // when a type's width should be known, we call checkwidth
@ -440,24 +436,18 @@ func checkwidth(t *types.Type) {
} }
func defercheckwidth() { func defercheckwidth() {
// we get out of sync on syntax errors, so don't be pedantic. defercalc++
if defercalc != 0 && nerrors == 0 {
Fatalf("defercheckwidth")
}
defercalc = 1
} }
func resumecheckwidth() { func resumecheckwidth() {
if defercalc == 0 { if defercalc == 1 {
Fatalf("resumecheckwidth")
}
for len(deferredTypeStack) > 0 { for len(deferredTypeStack) > 0 {
t := deferredTypeStack[len(deferredTypeStack)-1] t := deferredTypeStack[len(deferredTypeStack)-1]
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1] deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
t.SetDeferwidth(false) t.SetDeferwidth(false)
dowidth(t) dowidth(t)
} }
}
defercalc = 0 defercalc--
} }

View File

@ -298,21 +298,10 @@ func (r *importReader) doDecl(n *Node) {
// We also need to defer width calculations until // We also need to defer width calculations until
// after the underlying type has been assigned. // after the underlying type has been assigned.
//
// TODO(mdempsky): Add nesting support directly to
// {defer,resume}checkwidth? Width calculations are
// already deferred during initial typechecking, but
// not when we're expanding inline function bodies, so
// we currently need to handle both cases here.
deferring := defercalc != 0
if !deferring {
defercheckwidth() defercheckwidth()
}
underlying := r.typ() underlying := r.typ()
copytype(typenod(t), underlying) copytype(typenod(t), underlying)
if !deferring {
resumecheckwidth() resumecheckwidth()
}
if underlying.IsInterface() { if underlying.IsInterface() {
break break

View File

@ -527,7 +527,6 @@ func Main(archInit func(*Arch)) {
// We also defer type alias declarations until phase 2 // We also defer type alias declarations until phase 2
// to avoid cycles like #18640. // to avoid cycles like #18640.
// TODO(gri) Remove this again once we have a fix for #25838. // TODO(gri) Remove this again once we have a fix for #25838.
defercheckwidth()
// Don't use range--typecheck can add closures to xtop. // Don't use range--typecheck can add closures to xtop.
timings.Start("fe", "typecheck", "top1") timings.Start("fe", "typecheck", "top1")
@ -549,7 +548,6 @@ func Main(archInit func(*Arch)) {
xtop[i] = typecheck(n, ctxStmt) xtop[i] = typecheck(n, ctxStmt)
} }
} }
resumecheckwidth()
// Phase 3: Type check function bodies. // Phase 3: Type check function bodies.
// Don't use range--typecheck can add closures to xtop. // Don't use range--typecheck can add closures to xtop.
@ -1035,7 +1033,6 @@ func loadsys() {
inimport = true inimport = true
typecheckok = true typecheckok = true
defercheckwidth()
typs := runtimeTypes() typs := runtimeTypes()
for _, d := range runtimeDecls { for _, d := range runtimeDecls {
@ -1052,7 +1049,6 @@ func loadsys() {
} }
typecheckok = false typecheckok = false
resumecheckwidth()
inimport = false inimport = false
} }

View File

@ -3669,9 +3669,7 @@ func typecheckdef(n *Node) {
} }
// regular type declaration // regular type declaration
if Curfn != nil {
defercheckwidth() defercheckwidth()
}
n.SetWalkdef(1) n.SetWalkdef(1)
setTypeNode(n, types.New(TFORW)) setTypeNode(n, types.New(TFORW))
n.Type.Sym = n.Sym n.Type.Sym = n.Sym
@ -3682,10 +3680,8 @@ func typecheckdef(n *Node) {
// but it was reported. Silence future errors. // but it was reported. Silence future errors.
n.Type.SetBroke(true) n.Type.SetBroke(true)
} }
if Curfn != nil {
resumecheckwidth() resumecheckwidth()
} }
}
ret: ret:
if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() { if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {

View File

@ -18,10 +18,10 @@ type I4 interface { // GC_ERROR "invalid recursive type"
I4 // GCCGO_ERROR "interface" I4 // GCCGO_ERROR "interface"
} }
type I5 interface { type I5 interface { // GC_ERROR "invalid recursive type"
I6 // GCCGO_ERROR "interface" I6 // GCCGO_ERROR "interface"
} }
type I6 interface { // GC_ERROR "invalid recursive type" type I6 interface {
I5 // GCCGO_ERROR "interface" I5 // GCCGO_ERROR "interface"
} }

View File

@ -6,10 +6,10 @@
package p package p
type I1 = interface { // ERROR "invalid recursive type" type I1 = interface {
I2 I2
} }
type I2 interface { type I2 interface { // ERROR "invalid recursive type"
I1 I1
} }