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:
parent
adf20ee3c5
commit
380ef6b759
@ -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--
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user