case ODEREF, ODOTPTR:
return true
+ case OXDOT:
+ // TODO(danscales): remove this case as we remove calls to the old
+ // typechecker in (*irgen).funcBody().
+ if base.Flag.G == 0 {
+ return false
+ }
+ fallthrough
case ODOT:
n := n.(*SelectorExpr)
return IsAddressable(n.X)
// than in typecheck.go.
func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.SelectorExpr) ir.Node {
x := g.expr(expr.X)
- if x.Type().Kind() == types.TTYPEPARAM {
+ if x.Type().HasTParam() {
// Leave a method call on a type param as an OXDOT, since it can
// only be fully transformed once it has an instantiated type.
n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value))
// Expressions
func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr {
- // TODO(mdempsky): Avoid typecheck.Expr. Probably just need to set OPTRLIT when appropriate.
- n := typecheck.Expr(typecheck.NodAddrAt(pos, x)).(*ir.AddrExpr)
+ n := typecheck.NodAddrAt(pos, x)
+ switch x.Op() {
+ case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
+ n.SetOp(ir.OPTRLIT)
+ }
typed(types.NewPtr(x.Type()), n)
return n
}
n.IsDDD = dots
if fun.Op() == ir.OXDOT {
- if fun.(*ir.SelectorExpr).X.Type().Kind() != types.TTYPEPARAM {
+ if !fun.(*ir.SelectorExpr).X.Type().HasTParam() {
base.FatalfAt(pos, "Expecting type param receiver in %v", fun)
}
// For methods called in a generic function, don't do any extra
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 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
+
+import "sync"
+
+// A _Lockable is a value that may be safely simultaneously accessed
+// from multiple goroutines via the Get and Set methods.
+type _Lockable[T any] struct {
+ T
+ mu sync.Mutex
+}
+
+// Get returns the value stored in a _Lockable.
+func (l *_Lockable[T]) get() T {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ return l.T
+}
+
+// set sets the value in a _Lockable.
+func (l *_Lockable[T]) set(v T) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ l.T = v
+}
+
+func main() {
+ sl := _Lockable[string]{T: "a"}
+ if got := sl.get(); got != "a" {
+ panic(got)
+ }
+ sl.set("b")
+ if got := sl.get(); got != "b" {
+ panic(got)
+ }
+
+ il := _Lockable[int]{T: 1}
+ if got := il.get(); got != 1 {
+ panic(got)
+ }
+ il.set(2)
+ if got := il.get(); got != 2 {
+ panic(got)
+ }
+}