}
// defer checkwidth calls until after we're done
- defercalc++
+ defercheckwidth()
lno := lineno
if asNode(t.Nod) != nil {
lineno = lno
- if defercalc == 1 {
- resumecheckwidth()
- } else {
- defercalc--
- }
+ resumecheckwidth()
}
// when a type's width should be known, we call checkwidth
}
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")
- }
-
- for len(deferredTypeStack) > 0 {
- t := deferredTypeStack[len(deferredTypeStack)-1]
- deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
- t.SetDeferwidth(false)
- dowidth(t)
+ 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--
}
// 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()
- }
+ defercheckwidth()
underlying := r.typ()
copytype(typenod(t), underlying)
- if !deferring {
- resumecheckwidth()
- }
+ resumecheckwidth()
if underlying.IsInterface() {
break
// 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")
xtop[i] = typecheck(n, ctxStmt)
}
}
- resumecheckwidth()
// Phase 3: Type check function bodies.
// Don't use range--typecheck can add closures to xtop.
inimport = true
typecheckok = true
- defercheckwidth()
typs := runtimeTypes()
for _, d := range runtimeDecls {
}
typecheckok = false
- resumecheckwidth()
inimport = false
}
}
// regular type declaration
- if Curfn != nil {
- defercheckwidth()
- }
+ defercheckwidth()
n.SetWalkdef(1)
setTypeNode(n, types.New(TFORW))
n.Type.Sym = n.Sym
// but it was reported. Silence future errors.
n.Type.SetBroke(true)
}
- if Curfn != nil {
- resumecheckwidth()
- }
+ resumecheckwidth()
}
ret:
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"
}
package p
-type I1 = interface { // ERROR "invalid recursive type"
+type I1 = interface {
I2
}
-type I2 interface {
+type I2 interface { // ERROR "invalid recursive type"
I1
}