mirror of
https://github.com/golang/go
synced 2024-11-12 02:50:25 -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:
parent
adf20ee3c5
commit
380ef6b759
@ -217,7 +217,7 @@ func dowidth(t *types.Type) {
|
||||
}
|
||||
|
||||
// defer checkwidth calls until after we're done
|
||||
defercalc++
|
||||
defercheckwidth()
|
||||
|
||||
lno := lineno
|
||||
if asNode(t.Nod) != nil {
|
||||
@ -391,11 +391,7 @@ func dowidth(t *types.Type) {
|
||||
|
||||
lineno = lno
|
||||
|
||||
if defercalc == 1 {
|
||||
resumecheckwidth()
|
||||
} else {
|
||||
defercalc--
|
||||
}
|
||||
}
|
||||
|
||||
// when a type's width should be known, we call checkwidth
|
||||
@ -440,24 +436,18 @@ func checkwidth(t *types.Type) {
|
||||
}
|
||||
|
||||
func defercheckwidth() {
|
||||
// we get out of sync on syntax errors, so don't be pedantic.
|
||||
if defercalc != 0 && nerrors == 0 {
|
||||
Fatalf("defercheckwidth")
|
||||
}
|
||||
defercalc = 1
|
||||
defercalc++
|
||||
}
|
||||
|
||||
func resumecheckwidth() {
|
||||
if defercalc == 0 {
|
||||
Fatalf("resumecheckwidth")
|
||||
}
|
||||
|
||||
if defercalc == 1 {
|
||||
for len(deferredTypeStack) > 0 {
|
||||
t := deferredTypeStack[len(deferredTypeStack)-1]
|
||||
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
|
||||
t.SetDeferwidth(false)
|
||||
dowidth(t)
|
||||
}
|
||||
}
|
||||
|
||||
defercalc = 0
|
||||
defercalc--
|
||||
}
|
||||
|
@ -298,21 +298,10 @@ func (r *importReader) doDecl(n *Node) {
|
||||
|
||||
// We also need to defer width calculations until
|
||||
// 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()
|
||||
}
|
||||
underlying := r.typ()
|
||||
copytype(typenod(t), underlying)
|
||||
if !deferring {
|
||||
resumecheckwidth()
|
||||
}
|
||||
|
||||
if underlying.IsInterface() {
|
||||
break
|
||||
|
@ -527,7 +527,6 @@ func Main(archInit func(*Arch)) {
|
||||
// We also defer type alias declarations until phase 2
|
||||
// to avoid cycles like #18640.
|
||||
// TODO(gri) Remove this again once we have a fix for #25838.
|
||||
defercheckwidth()
|
||||
|
||||
// Don't use range--typecheck can add closures to xtop.
|
||||
timings.Start("fe", "typecheck", "top1")
|
||||
@ -549,7 +548,6 @@ func Main(archInit func(*Arch)) {
|
||||
xtop[i] = typecheck(n, ctxStmt)
|
||||
}
|
||||
}
|
||||
resumecheckwidth()
|
||||
|
||||
// Phase 3: Type check function bodies.
|
||||
// Don't use range--typecheck can add closures to xtop.
|
||||
@ -1035,7 +1033,6 @@ func loadsys() {
|
||||
|
||||
inimport = true
|
||||
typecheckok = true
|
||||
defercheckwidth()
|
||||
|
||||
typs := runtimeTypes()
|
||||
for _, d := range runtimeDecls {
|
||||
@ -1052,7 +1049,6 @@ func loadsys() {
|
||||
}
|
||||
|
||||
typecheckok = false
|
||||
resumecheckwidth()
|
||||
inimport = false
|
||||
}
|
||||
|
||||
|
@ -3669,9 +3669,7 @@ func typecheckdef(n *Node) {
|
||||
}
|
||||
|
||||
// regular type declaration
|
||||
if Curfn != nil {
|
||||
defercheckwidth()
|
||||
}
|
||||
n.SetWalkdef(1)
|
||||
setTypeNode(n, types.New(TFORW))
|
||||
n.Type.Sym = n.Sym
|
||||
@ -3682,10 +3680,8 @@ func typecheckdef(n *Node) {
|
||||
// but it was reported. Silence future errors.
|
||||
n.Type.SetBroke(true)
|
||||
}
|
||||
if Curfn != nil {
|
||||
resumecheckwidth()
|
||||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
|
||||
|
@ -18,10 +18,10 @@ type I4 interface { // GC_ERROR "invalid recursive type"
|
||||
I4 // GCCGO_ERROR "interface"
|
||||
}
|
||||
|
||||
type I5 interface {
|
||||
type I5 interface { // GC_ERROR "invalid recursive type"
|
||||
I6 // GCCGO_ERROR "interface"
|
||||
}
|
||||
|
||||
type I6 interface { // GC_ERROR "invalid recursive type"
|
||||
type I6 interface {
|
||||
I5 // GCCGO_ERROR "interface"
|
||||
}
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
package p
|
||||
|
||||
type I1 = interface { // ERROR "invalid recursive type"
|
||||
type I1 = interface {
|
||||
I2
|
||||
}
|
||||
|
||||
type I2 interface {
|
||||
type I2 interface { // ERROR "invalid recursive type"
|
||||
I1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user