From 8e658eee9c7a67a8a79a8308695920ac9917566c Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 16 Jan 2024 16:59:31 -0800 Subject: [PATCH] cmd/compile: call types2.Unalias to be ready for GODEBUG=gotypesalias=1 types2.Unalias is not needed if we know we have a core or underlying type. Also, types of declared functions (signatures) cannot be aliases (this includes tuples). Fixes #65125. Change-Id: I1faa26b66f6c646719e830dd661136fae86f3775 Reviewed-on: https://go-review.googlesource.com/c/go/+/556036 Run-TryBot: Robert Griesemer Reviewed-by: Mauri de Souza Meneguzzo TryBot-Result: Gopher Robot Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/noder/helpers.go | 5 +++-- src/cmd/compile/internal/noder/irgen.go | 4 ++-- src/cmd/compile/internal/noder/writer.go | 18 +++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go index f9e3838fd9..0bff71e658 100644 --- a/src/cmd/compile/internal/noder/helpers.go +++ b/src/cmd/compile/internal/noder/helpers.go @@ -80,7 +80,7 @@ func idealType(tv syntax.TypeAndValue) types2.Type { // types2 mostly satisfies this expectation already. But there are a few // cases where the Go spec doesn't require converting to concrete type, // and so types2 leaves them untyped. So we need to fix those up here. - typ := tv.Type + typ := types2.Unalias(tv.Type) if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 { switch basic.Kind() { case types2.UntypedNil: @@ -109,13 +109,14 @@ func idealType(tv syntax.TypeAndValue) types2.Type { } func isTypeParam(t types2.Type) bool { - _, ok := t.(*types2.TypeParam) + _, ok := types2.Unalias(t).(*types2.TypeParam) return ok } // isNotInHeap reports whether typ is or contains an element of type // runtime/internal/sys.NotInHeap. func isNotInHeap(typ types2.Type) bool { + typ = types2.Unalias(typ) if named, ok := typ.(*types2.Named); ok { if obj := named.Obj(); obj.Name() == "nih" && obj.Pkg().Path() == "runtime/internal/sys" { return true diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go index d909f3467b..e0b7bb946d 100644 --- a/src/cmd/compile/internal/noder/irgen.go +++ b/src/cmd/compile/internal/noder/irgen.go @@ -97,7 +97,7 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) { for _, file := range files { syntax.Inspect(file, func(n syntax.Node) bool { if n, ok := n.(*syntax.InterfaceType); ok { - if f.hasCycle(n.GetTypeInfo().Type.(*types2.Interface)) { + if f.hasCycle(types2.Unalias(n.GetTypeInfo().Type).(*types2.Interface)) { base.ErrorfAt(m.makeXPos(n.Pos()), errors.InvalidTypeCycle, "invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)") for typ := range f.cyclic { @@ -171,7 +171,7 @@ func (f *cycleFinder) hasCycle(typ *types2.Interface) bool { // visit recursively walks typ0 to check any referenced interface types. func (f *cycleFinder) visit(typ0 types2.Type) bool { for { // loop for tail recursion - switch typ := typ0.(type) { + switch typ := types2.Unalias(typ0).(type) { default: base.Fatalf("unexpected type: %T", typ) diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 46d5213694..e5894c9505 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -217,7 +217,7 @@ type itabInfo struct { // generic function or method. func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int { for idx, implicit := range dict.implicits { - if implicit.Type().(*types2.TypeParam) == typ { + if types2.Unalias(implicit.Type()).(*types2.TypeParam) == typ { return idx } } @@ -498,7 +498,7 @@ func (pw *pkgWriter) typIdx(typ types2.Type, dict *writerDict) typeInfo { w := pw.newWriter(pkgbits.RelocType, pkgbits.SyncTypeIdx) w.dict = dict - switch typ := typ.(type) { + switch typ := types2.Unalias(typ).(type) { default: base.Fatalf("unexpected type: %v (%T)", typ, typ) @@ -889,7 +889,7 @@ func (w *writer) objDict(obj types2.Object, dict *writerDict) { // parameter is constrained to `int | uint` but then never used in // arithmetic/conversions/etc, we could shape those together. for _, implicit := range dict.implicits { - tparam := implicit.Type().(*types2.TypeParam) + tparam := types2.Unalias(implicit.Type()).(*types2.TypeParam) w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet()) } for i := 0; i < ntparams; i++ { @@ -2124,7 +2124,7 @@ func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *ty // Method on a type parameter. These require an indirect call // through the current function's runtime dictionary. - if typeParam, ok := recv.(*types2.TypeParam); w.Bool(ok) { + if typeParam, ok := types2.Unalias(recv).(*types2.TypeParam); w.Bool(ok) { typeParamIdx := w.dict.typeParamIndex(typeParam) methodInfo := w.p.selectorIdx(fun) @@ -2137,7 +2137,7 @@ func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *ty } if !isInterface(recv) { - if named, ok := deref2(recv).(*types2.Named); ok { + if named, ok := types2.Unalias(deref2(recv)).(*types2.Named); ok { obj, targs := splitNamed(named) info := w.p.objInstIdx(obj, targs, w.dict) @@ -2363,7 +2363,7 @@ func (w *writer) varDictIndex(obj *types2.Var) { } func isUntyped(typ types2.Type) bool { - basic, ok := typ.(*types2.Basic) + basic, ok := types2.Unalias(typ).(*types2.Basic) return ok && basic.Info()&types2.IsUntyped != 0 } @@ -2416,7 +2416,7 @@ func (w *writer) exprType(iface types2.Type, typ syntax.Expr) { // If typ is a type parameter, then isInterface reports an internal // compiler error instead. func isInterface(typ types2.Type) bool { - if _, ok := typ.(*types2.TypeParam); ok { + if _, ok := types2.Unalias(typ).(*types2.TypeParam); ok { // typ is a type parameter and may be instantiated as either a // concrete or interface type, so the writer can't depend on // knowing this. @@ -2867,7 +2867,7 @@ func (pw *pkgWriter) isBuiltin(expr syntax.Expr, builtin string) bool { // recvBase returns the base type for the given receiver parameter. func recvBase(recv *types2.Var) *types2.Named { - typ := recv.Type() + typ := types2.Unalias(recv.Type()) if ptr, ok := typ.(*types2.Pointer); ok { typ = ptr.Elem() } @@ -2945,7 +2945,7 @@ func asWasmImport(p syntax.Pragma) *WasmImport { // isPtrTo reports whether from is the type *to. func isPtrTo(from, to types2.Type) bool { - ptr, ok := from.(*types2.Pointer) + ptr, ok := types2.Unalias(from).(*types2.Pointer) return ok && types2.Identical(ptr.Elem(), to) } -- 2.48.1