From 8854368cb076ea9a2b71c8b3c8f675a8e19b751c Mon Sep 17 00:00:00 2001 From: Dan Scales Date: Fri, 24 Sep 2021 08:57:06 -0700 Subject: [PATCH] cmd/compile: deal with blank nodes with typeparam type during stenciling Deal correctly with a blank local variable with type param type. This is a special case, because a blank local variable is not in the fn.Dcl list. In this case, we must explicitly create a new blank node with the correct substituted type, so we have correct types if the blank local variable has an initializing assignment. Fixes #48602 Change-Id: I903ea44b29934e180404e32800773b7309bf297b Reviewed-on: https://go-review.googlesource.com/c/go/+/352117 Run-TryBot: Dan Scales TryBot-Result: Go Bot Reviewed-by: Cuong Manh Le Trust: Cuong Manh Le Trust: Dan Scales --- src/cmd/compile/internal/noder/stencil.go | 6 ++++++ test/typeparam/issue48602.go | 25 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/typeparam/issue48602.go diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index cf8641d60e..23f53bac04 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -912,6 +912,12 @@ func (subst *subster) node(n ir.Node) ir.Node { if v := subst.ts.Vars[x.(*ir.Name)]; v != nil { return v } + if ir.IsBlank(x) { + // Special case, because a blank local variable is + // not in the fn.Dcl list. + m := ir.NewNameAt(x.Pos(), ir.BlankNode.Sym()) + return typed(subst.ts.Typ(x.Type()), m) + } return x case ir.ONONAME: // This handles the identifier in a type switch guard diff --git a/test/typeparam/issue48602.go b/test/typeparam/issue48602.go new file mode 100644 index 0000000000..53ce20e6ea --- /dev/null +++ b/test/typeparam/issue48602.go @@ -0,0 +1,25 @@ +// 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 + +type Iterator[T any] interface { + Iterate(fn T) +} + +type IteratorFunc[T any] func(fn T) + +func (f IteratorFunc[T]) Iterate(fn T) { + f(fn) +} + +func Foo[R any]() { + var _ Iterator[R] = IteratorFunc[R](nil) +} + +func main() { + Foo[int]() +}