mirror of
https://github.com/golang/go
synced 2024-11-21 16:54:46 -07:00
types2, go/types: fix instantiation of named 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 <gri@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
d8c7230c97
commit
9b4b4ae585
@ -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
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"cmd/compile/internal/syntax"
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/buildcfg"
|
||||
. "internal/types/errors"
|
||||
)
|
||||
|
||||
@ -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)
|
||||
@ -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
|
||||
|
@ -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:
|
||||
|
@ -137,10 +137,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 token.Pos, orig *Alias, targs []Type, ctxt *Context) *Alias {
|
||||
func (check *Checker) newAliasInstance(pos token.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
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/token"
|
||||
"internal/buildcfg"
|
||||
. "internal/types/errors"
|
||||
)
|
||||
|
||||
@ -129,8 +130,9 @@ func (check *Checker) instance(pos token.Pos, orig genericType, targs []Type, ex
|
||||
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)
|
||||
@ -141,7 +143,7 @@ func (check *Checker) instance(pos token.Pos, orig genericType, targs []Type, ex
|
||||
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
|
||||
|
@ -118,7 +118,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:
|
||||
|
15
test/fixedbugs/issue68580.go
Normal file
15
test/fixedbugs/issue68580.go
Normal file
@ -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]
|
Loading…
Reference in New Issue
Block a user