// Phase 1: const, type, and names and types of funcs.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
+ //
+ // 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")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
- if op := n.Op; op != ODCL && op != OAS && op != OAS2 {
+ if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias) {
xtop[i] = typecheck(n, Etop)
}
}
timings.Start("fe", "typecheck", "top2")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
- if op := n.Op; op == ODCL || op == OAS || op == OAS2 {
+ if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias {
xtop[i] = typecheck(n, Etop)
}
}
// since it would expand indefinitely when aliases
// are substituted.
cycle := cycleFor(n)
- for _, n := range cycle {
- if n.Name != nil && !n.Name.Param.Alias {
+ for _, n1 := range cycle {
+ if n1.Name != nil && !n1.Name.Param.Alias {
+ // Cycle is ok. But if n is an alias type and doesn't
+ // have a type yet, we have a recursive type declaration
+ // with aliases that we can't handle properly yet.
+ // Report an error rather than crashing later.
+ if n.Name != nil && n.Name.Param.Alias && n.Type == nil {
+ lineno = n.Pos
+ Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
+ }
lineno = lno
return n
}
"issue22200b.go", // go/types does not have constraints on stack size
"issue25507.go", // go/types does not have constraints on stack size
"issue20780.go", // go/types does not have constraints on stack size
+ "issue27232.go", // go/types has a bug with alias type (issue #28576)
)
}
d = c
)
-// The compiler reports an incorrect (non-alias related)
-// type cycle here (via dowith()). Disabled for now.
+// The compiler cannot handle these cases. Disabled for now.
// See issue #25838.
/*
type (
i = j
j = e
)
-*/
type (
a1 struct{ *b1 }
b2 = c2
c2 struct{ *b2 }
)
+*/
-// errorcheck
+// compile
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
package p
+// The compiler cannot handle this. Disabled for now.
+// See issue #25838.
+/*
type I1 = interface {
I2
}
-type I2 interface { // ERROR "invalid recursive type"
+type I2 interface {
I1
}
+*/
}
type P = interface {
- I() M
+ // The compiler cannot handle this case. Disabled for now.
+ // See issue #25838.
+ // I() M
}
func main() {}
--- /dev/null
+// compile
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type F = func(T)
+
+type T interface {
+ m(F)
+}
+
+type t struct{}
+
+func (t) m(F) {}
+
+var _ T = &t{}
--- /dev/null
+// compile
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// 1st test case from issue
+type F = func(E) // compiles if not type alias or moved below E struct
+type E struct {
+ f F
+}
+
+var x = E{func(E) {}}
+
+// 2nd test case from issue
+type P = *S
+type S struct {
+ p P
+}