Skip to content

Commit

Permalink
[release-branch.go1.23] types2, go/types: fix instantiation of named …
Browse files Browse the repository at this point in the history
…type with generic alias

The typechecker is assuming that alias instances cannot be reached from
a named type. However, when type parameters on aliases are permited, it
can happen.

This CL changes the typechecker to propagate the correct named instance
is being expanded.

Updates #46477
Fixes #68580

Change-Id: Id0879021f4640c0fefe277701d5096c649413811
Reviewed-on: https://go-review.googlesource.com/c/go/+/601115
Auto-Submit: Robert Griesemer <[email protected]>
Reviewed-by: Dmitri Shuralyov <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Robert Griesemer <[email protected]>
Auto-Submit: Cuong Manh Le <[email protected]>
Reviewed-on: https://go-review.googlesource.com/c/go/+/601116
  • Loading branch information
cuonglm authored and gopherbot committed Jul 26, 2024
1 parent 3509415 commit c9940fe
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/types2/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ func (check *Checker) newAlias(obj *TypeName, rhs Type) *Alias {
// newAliasInstance creates a new alias instance for the given origin and type
// arguments, recording pos as the position of its synthetic object (for error
// reporting).
func (check *Checker) newAliasInstance(pos syntax.Pos, orig *Alias, targs []Type, ctxt *Context) *Alias {
func (check *Checker) newAliasInstance(pos syntax.Pos, orig *Alias, targs []Type, expanding *Named, ctxt *Context) *Alias {
assert(len(targs) > 0)
obj := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
rhs := check.subst(pos, orig.fromRHS, makeSubstMap(orig.TypeParams().list(), targs), nil, ctxt)
rhs := check.subst(pos, orig.fromRHS, makeSubstMap(orig.TypeParams().list(), targs), expanding, ctxt)
res := check.newAlias(obj, rhs)
res.orig = orig
res.tparams = orig.tparams
Expand Down
8 changes: 5 additions & 3 deletions src/cmd/compile/internal/types2/instantiate.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"cmd/compile/internal/syntax"
"errors"
"fmt"
"internal/buildcfg"
. "internal/types/errors"
)

Expand Down Expand Up @@ -126,8 +127,9 @@ func (check *Checker) instance(pos syntax.Pos, orig genericType, targs []Type, e
res = check.newNamedInstance(pos, orig, targs, expanding) // substituted lazily

case *Alias:
// TODO(gri) is this correct?
assert(expanding == nil) // Alias instances cannot be reached from Named types
if !buildcfg.Experiment.AliasTypeParams {
assert(expanding == nil) // Alias instances cannot be reached from Named types
}

tparams := orig.TypeParams()
// TODO(gri) investigate if this is needed (type argument and parameter count seem to be correct here)
Expand All @@ -138,7 +140,7 @@ func (check *Checker) instance(pos syntax.Pos, orig genericType, targs []Type, e
return orig // nothing to do (minor optimization)
}

return check.newAliasInstance(pos, orig, targs, ctxt)
return check.newAliasInstance(pos, orig, targs, expanding, ctxt)

case *Signature:
assert(expanding == nil) // function instances cannot be reached from Named types
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/compile/internal/types2/subst.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (subst *subster) typ(typ Type) Type {
// that has a type argument for it.
targs, updated := subst.typeList(t.TypeArgs().list())
if updated {
return subst.check.newAliasInstance(subst.pos, t.orig, targs, subst.ctxt)
return subst.check.newAliasInstance(subst.pos, t.orig, targs, subst.expanding, subst.ctxt)
}

case *Array:
Expand Down
4 changes: 2 additions & 2 deletions src/go/types/alias.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions src/go/types/instantiate.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/go/types/subst.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/fixedbugs/issue68580.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// compile -goexperiment aliastypeparams

// Copyright 2024 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 A[P any] = struct{ _ P }

type N[P any] A[P]

func f[P any](N[P]) {}

var _ = f[int]

0 comments on commit c9940fe

Please sign in to comment.