NoRefName int `help:"do not include referenced symbol names in object file"`
PCTab string `help:"print named pc-value table\nOne of: pctospadj, pctofile, pctoline, pctoinline, pctopcdata"`
Panic int `help:"show all compiler panics"`
+ Reshape int `help:"print information about expression reshaping"`
Slice int `help:"print information about slice compilation"`
SoftFloat int `help:"force compiler to emit soft-float code"`
SyncFrames int `help:"how many writer stack frames to include at sync points in unified export data"`
exprNil
exprFuncInst
exprRecv
+ exprReshape
)
type codeAssign int
}
}
-// A writer provides APIs for reading an individual element.
+// A reader provides APIs for reading an individual element.
type reader struct {
pkgbits.Decoder
typ := r.exprType()
return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
+ case exprReshape:
+ typ := r.typ()
+ x := r.expr()
+
+ if types.IdenticalStrict(x.Type(), typ) {
+ return x
+ }
+
+ // Comparison expressions are constructed as "untyped bool" still.
+ //
+ // TODO(mdempsky): It should be safe to reshape them here too, but
+ // maybe it's better to construct them with the proper type
+ // instead.
+ if x.Type() == types.UntypedBool && typ.IsBoolean() {
+ return x
+ }
+
+ base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
+ base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
+
+ // We use ir.HasUniquePos here as a check that x only appears once
+ // in the AST, so it's okay for us to call SetType without
+ // breaking any other uses of it.
+ //
+ // Notably, any ONAMEs should already have the exactly right shape
+ // type and been caught by types.IdenticalStrict above.
+ base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
+
+ if base.Debug.Reshape != 0 {
+ base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
+ }
+
+ x.SetType(typ)
+ return x
+
case exprConvert:
implicit := r.Bool()
typ := r.typ()
w.typ(tv.Type)
return
}
+
+ // With shape types (and particular pointer shaping), we may have
+ // an expression of type "go.shape.*uint8", but need to reshape it
+ // to another shape-identical type to allow use in field
+ // selection, indexing, etc.
+ if typ := tv.Type; !tv.IsBuiltin() && !isTuple(typ) && !isUntyped(typ) {
+ w.Code(exprReshape)
+ w.typ(typ)
+ // fallthrough
+ }
}
if obj != nil {
return ok && basic.Info()&types2.IsUntyped != 0
}
+func isTuple(typ types2.Type) bool {
+ _, ok := typ.(*types2.Tuple)
+ return ok
+}
+
func (w *writer) itab(typ, iface types2.Type) {
typ = types2.Default(typ)
iface = types2.Default(iface)
--- /dev/null
+// run
+
+// 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 main
+
+type node[T any] struct {
+ items items[T]
+ children items[*node[T]]
+}
+
+func (n *node[T]) f(i int, j int) bool {
+ if len(n.children[i].items) < j {
+ return false
+ }
+ return true
+}
+
+type items[T any] []T
+
+func main() {
+ _ = node[int]{}
+ _ = f[int]
+}
+
+type s[T, U any] struct {
+ a T
+ c U
+}
+
+func f[T any]() {
+ var x s[*struct{ b T }, *struct{ d int }]
+ _ = x.a.b
+ _ = x.c.d
+}