Commit 380ef6b7 authored by Matthew Dempsky's avatar Matthew Dempsky

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: default avatarCuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent adf20ee3
......@@ -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
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment