// constructed.
var todoBodies []*ir.Func
-// todoBodiesDone signals that we constructed all function in todoBodies.
-// This is necessary to prevent reader.addBody adds thing to todoBodies
-// when nested inlining happens.
-var todoBodiesDone = false
-
func (r *reader) addBody(fn *ir.Func) {
pri := pkgReaderIndex{r.p, r.Reloc(pkgbits.RelocBody), r.dict}
bodyReader[fn] = pri
return
}
- if r.curfn == nil && !todoBodiesDone {
+ if r.curfn == nil {
todoBodies = append(todoBodies, fn)
return
}
r.curfn.Body = r.stmts()
r.curfn.Endlineno = r.pos()
+ // TODO(mdempsky): This shouldn't be necessary. Inlining might
+ // read in new function/method declarations, which could
+ // potentially be recursively inlined themselves; but we shouldn't
+ // need to read in the non-inlined bodies for the declarations
+ // themselves. But currently it's an easy fix to #50552.
+ readBodies(typecheck.Target)
+
deadcode.Func(r.curfn)
// Replace any "return" statements within the function body.
}
}
+ readBodies(target)
+
+ // Check that nothing snuck past typechecking.
+ for _, n := range target.Decls {
+ if n.Typecheck() == 0 {
+ base.FatalfAt(n.Pos(), "missed typecheck: %v", n)
+ }
+
+ // For functions, check that at least their first statement (if
+ // any) was typechecked too.
+ if fn, ok := n.(*ir.Func); ok && len(fn.Body) != 0 {
+ if stmt := fn.Body[0]; stmt.Typecheck() == 0 {
+ base.FatalfAt(stmt.Pos(), "missed typecheck: %v", stmt)
+ }
+ }
+ }
+
+ base.ExitIfErrors() // just in case
+}
+
+// readBodies reads in bodies for any
+func readBodies(target *ir.Package) {
// Don't use range--bodyIdx can add closures to todoBodies.
for len(todoBodies) > 0 {
// The order we expand bodies doesn't matter, so pop from the end
}
}
todoBodies = nil
- todoBodiesDone = true
-
- // Check that nothing snuck past typechecking.
- for _, n := range target.Decls {
- if n.Typecheck() == 0 {
- base.FatalfAt(n.Pos(), "missed typecheck: %v", n)
- }
-
- // For functions, check that at least their first statement (if
- // any) was typechecked too.
- if fn, ok := n.(*ir.Func); ok && len(fn.Body) != 0 {
- if stmt := fn.Body[0]; stmt.Typecheck() == 0 {
- base.FatalfAt(stmt.Pos(), "missed typecheck: %v", stmt)
- }
- }
- }
-
- base.ExitIfErrors() // just in case
}
// writePkgStub type checks the given parsed source files,
"typeparam/typeswitch2.go", // duplicate case failure due to stenciling
"typeparam/typeswitch3.go", // duplicate case failure due to stenciling
"typeparam/typeswitch4.go", // duplicate case failure due to stenciling
- "typeparam/issue50552.go", // gives missing method for instantiated type
)
func setOf(keys ...string) map[string]bool {
--- /dev/null
+// Copyright 2022 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 a
+
+func F() interface{} { return new(T[int]) }
+
+type T[P any] int
+
+func (x *T[P]) One() int { return x.Two() }
+func (x *T[P]) Two() int { return 0 }
--- /dev/null
+// Copyright 2022 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 b
+
+import "./a"
+
+var _ = a.F()
--- /dev/null
+// compiledir
+
+// Copyright 2022 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 ignored