From: Robert Griesemer Date: Thu, 15 Jan 2026 00:10:00 +0000 (-0800) Subject: go/types, types2: remove support for gotypesalias GODEBUG flag X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6edb9f9c51f4f9042563f6fcf68701d1fed33c8f;p=gostls13.git go/types, types2: remove support for gotypesalias GODEBUG flag For #76472. Change-Id: Ia51b41639637b1de916625e73c26f625382be305 Reviewed-on: https://go-review.googlesource.com/c/go/+/736441 Reviewed-by: Alan Donovan LUCI-TryBot-Result: Go LUCI Auto-Submit: Robert Griesemer Reviewed-by: Robert Griesemer Commit-Queue: Robert Griesemer --- diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go index 05f0affe8a..387379d2a1 100644 --- a/src/cmd/compile/internal/noder/irgen.go +++ b/src/cmd/compile/internal/noder/irgen.go @@ -56,7 +56,6 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info, map[* IgnoreBranchErrors: true, // parser already checked via syntax.CheckBranches mode Importer: &importer, Sizes: types2.SizesFor("gc", buildcfg.GOARCH), - EnableAlias: true, } if base.Flag.ErrorURL { conf.ErrorURL = " [go.dev/e/%s]" diff --git a/src/cmd/compile/internal/types2/alias.go b/src/cmd/compile/internal/types2/alias.go index d306600ebd..11581bd5a7 100644 --- a/src/cmd/compile/internal/types2/alias.go +++ b/src/cmd/compile/internal/types2/alias.go @@ -21,24 +21,6 @@ import ( // // Like a defined ([Named]) type, an alias type has a name. // Use the [Alias.Obj] method to access its [TypeName] object. -// -// Historically, Alias types were not materialized so that, in the example -// above, A's type was represented by a Basic (int), not an Alias -// whose [Alias.Rhs] is int. But Go 1.24 allows you to declare an -// alias type with type parameters or arguments: -// -// type Set[K comparable] = map[K]bool -// s := make(Set[String]) -// -// and this requires that Alias types be materialized. Use the -// [Alias.TypeParams] and [Alias.TypeArgs] methods to access them. -// -// To ease the transition, the Alias type was introduced in go1.22, -// but the type-checker would not construct values of this type unless -// the GODEBUG=gotypesalias=1 environment variable was provided. -// Starting in go1.23, this variable is enabled by default. -// This setting also causes the predeclared type "any" to be -// represented as an Alias, not a bare [Interface]. type Alias struct { obj *TypeName // corresponding declared alias object orig *Alias // original, uninstantiated alias diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go index 8752eff992..901984814e 100644 --- a/src/cmd/compile/internal/types2/api.go +++ b/src/cmd/compile/internal/types2/api.go @@ -175,16 +175,6 @@ type Config struct { // of an error message. ErrorURL must be a format string containing // exactly one "%s" format, e.g. "[go.dev/e/%s]". ErrorURL string - - // If EnableAlias is set, alias declarations produce an Alias type. Otherwise - // the alias information is only in the type name, which points directly to - // the actual (aliased) type. - // - // This setting must not differ among concurrent type-checking operations, - // since it affects the behavior of Universe.Lookup("any"). - // - // This flag will eventually be removed (with Go 1.24 at the earliest). - EnableAlias bool } // Info holds result type information for a type-checked package. diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go index 4b7012e6c4..a3bb085317 100644 --- a/src/cmd/compile/internal/types2/api_test.go +++ b/src/cmd/compile/internal/types2/api_test.go @@ -2979,7 +2979,6 @@ func TestTooNew(t *testing.T) { // This is a regression test for #66704. func TestUnaliasTooSoonInCycle(t *testing.T) { - t.Setenv("GODEBUG", "gotypesalias=1") const src = `package a var x T[B] // this appears to cause Unalias to be called on B while still Invalid @@ -3005,7 +3004,7 @@ type B = C type C = int ` - pkg := mustTypecheck(src, &Config{EnableAlias: true}, nil) + pkg := mustTypecheck(src, nil, nil) A := pkg.Scope().Lookup("A") got, want := A.Type().(*Alias).Rhs().String(), "p.B" @@ -3014,28 +3013,6 @@ type C = int } } -// Test the hijacking described of "any" described in golang/go#66921, for -// (concurrent) type checking. -func TestAnyHijacking_Check(t *testing.T) { - for _, enableAlias := range []bool{false, true} { - t.Run(fmt.Sprintf("EnableAlias=%t", enableAlias), func(t *testing.T) { - var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() - pkg := mustTypecheck("package p; var x any", &Config{EnableAlias: enableAlias}, nil) - x := pkg.Scope().Lookup("x") - if _, gotAlias := x.Type().(*Alias); gotAlias != enableAlias { - t.Errorf(`Lookup("x").Type() is %T: got Alias: %t, want %t`, x.Type(), gotAlias, enableAlias) - } - }() - } - wg.Wait() - }) - } -} - // This test function only exists for go/types. // func TestVersionIssue69477(t *testing.T) diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go index 42218b4caf..d714976f74 100644 --- a/src/cmd/compile/internal/types2/check.go +++ b/src/cmd/compile/internal/types2/check.go @@ -12,7 +12,6 @@ import ( "go/constant" . "internal/types/errors" "os" - "sync/atomic" ) // nopos indicates an unknown position @@ -24,29 +23,6 @@ const debug = false // leave on during development // position tracing for panics during type checking const tracePos = true -// _aliasAny changes the behavior of [Scope.Lookup] for "any" in the -// [Universe] scope. -// -// This is necessary because while Alias creation is controlled by -// [Config.EnableAlias], the representation of "any" is a global. In -// [Scope.Lookup], we select this global representation based on the result of -// [aliasAny], but as a result need to guard against this behavior changing -// during the type checking pass. Therefore we implement the following rule: -// any number of goroutines can type check concurrently with the same -// EnableAlias value, but if any goroutine tries to type check concurrently -// with a different EnableAlias value, we panic. -// -// To achieve this, _aliasAny is a state machine: -// -// 0: no type checking is occurring -// negative: type checking is occurring without EnableAlias set -// positive: type checking is occurring with EnableAlias set -var _aliasAny int32 - -func aliasAny() bool { - return atomic.LoadInt32(&_aliasAny) >= 0 // default true -} - // exprInfo stores information about an untyped expression. type exprInfo struct { isLhs bool // expression is lhs operand of a shift with delayed type-check @@ -200,34 +176,6 @@ func (check *Checker) addDeclDep(to Object) { from.addDep(to) } -// Note: The following three alias-related functions are only used -// when Alias types are not enabled. - -// brokenAlias records that alias doesn't have a determined type yet. -// It also sets alias.typ to Typ[Invalid]. -// Not used if check.conf.EnableAlias is set. -func (check *Checker) brokenAlias(alias *TypeName) { - assert(!check.conf.EnableAlias) - if check.brokenAliases == nil { - check.brokenAliases = make(map[*TypeName]bool) - } - check.brokenAliases[alias] = true - alias.typ = Typ[Invalid] -} - -// validAlias records that alias has the valid type typ (possibly Typ[Invalid]). -func (check *Checker) validAlias(alias *TypeName, typ Type) { - assert(!check.conf.EnableAlias) - delete(check.brokenAliases, alias) - alias.typ = typ -} - -// isBrokenAlias reports whether alias doesn't have a determined type yet. -func (check *Checker) isBrokenAlias(alias *TypeName) bool { - assert(!check.conf.EnableAlias) - return check.brokenAliases[alias] -} - func (check *Checker) rememberUntyped(e syntax.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) { m := check.untyped if m == nil { @@ -472,20 +420,6 @@ func (check *Checker) Files(files []*syntax.File) (err error) { // syntax is properly type annotated even in a package containing // errors. func (check *Checker) checkFiles(files []*syntax.File) { - // Ensure that EnableAlias is consistent among concurrent type checking - // operations. See the documentation of [_aliasAny] for details. - if check.conf.EnableAlias { - if atomic.AddInt32(&_aliasAny, 1) <= 0 { - panic("EnableAlias set while !EnableAlias type checking is ongoing") - } - defer atomic.AddInt32(&_aliasAny, -1) - } else { - if atomic.AddInt32(&_aliasAny, -1) >= 0 { - panic("!EnableAlias set while EnableAlias type checking is ongoing") - } - defer atomic.AddInt32(&_aliasAny, 1) - } - print := func(msg string) { if check.conf.Trace { fmt.Println() diff --git a/src/cmd/compile/internal/types2/check_test.go b/src/cmd/compile/internal/types2/check_test.go index 8b97a9f676..99bfcc94bf 100644 --- a/src/cmd/compile/internal/types2/check_test.go +++ b/src/cmd/compile/internal/types2/check_test.go @@ -112,8 +112,6 @@ func parseFlags(src []byte, flags *flag.FlagSet) error { // testFiles type-checks the package consisting of the given files, and // compares the resulting errors with the ERROR annotations in the source. -// Except for manual tests, each package is type-checked twice, once without -// use of Alias types, and once with Alias types. // // The srcs slice contains the file content for the files named in the // filenames slice. The colDelta parameter specifies the tolerance for position @@ -122,16 +120,6 @@ func parseFlags(src []byte, flags *flag.FlagSet) error { // // If provided, opts may be used to mutate the Config before type-checking. func testFiles(t *testing.T, filenames []string, srcs [][]byte, colDelta uint, manual bool, opts ...func(*Config)) { - enableAlias := true - opts = append(opts, func(conf *Config) { conf.EnableAlias = enableAlias }) - testFilesImpl(t, filenames, srcs, colDelta, manual, opts...) - if !manual { - enableAlias = false - testFilesImpl(t, filenames, srcs, colDelta, manual, opts...) - } -} - -func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, colDelta uint, manual bool, opts ...func(*Config)) { if len(filenames) == 0 { t.Fatal("no source files") } @@ -171,12 +159,11 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, colDelta uin } // apply flag setting (overrides custom configuration) - var goexperiment, gotypesalias string + var goexperiment string flags := flag.NewFlagSet("", flag.PanicOnError) flags.StringVar(&conf.GoVersion, "lang", "", "") flags.StringVar(&goexperiment, "goexperiment", "", "") flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "") - flags.StringVar(&gotypesalias, "gotypesalias", "", "") if err := parseFlags(srcs[0], flags); err != nil { t.Fatal(err) } @@ -186,11 +173,6 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, colDelta uin defer revert() } - // By default, gotypesalias is not set. - if gotypesalias != "" { - conf.EnableAlias = gotypesalias != "0" - } - // Provide Config.Info with all maps so that info recording is tested. info := Info{ Types: make(map[syntax.Expr]TypeAndValue), diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go index 25152545ec..be9c63bc8c 100644 --- a/src/cmd/compile/internal/types2/decl.go +++ b/src/cmd/compile/internal/types2/decl.go @@ -199,27 +199,7 @@ loop: tparCycle = true break loop } - - // Determine if the type name is an alias or not. For - // package-level objects, use the object map which - // provides syntactic information (which doesn't rely - // on the order in which the objects are set up). For - // local objects, we can rely on the order, so use - // the object's predicate. - // TODO(gri) It would be less fragile to always access - // the syntactic information. We should consider storing - // this information explicitly in the object. - var alias bool - if check.conf.EnableAlias { - alias = obj.IsAlias() - } else { - if d := check.objMap[obj]; d != nil { - alias = d.tdecl.Alias // package-level object - } else { - alias = obj.IsAlias() // function local object - } - } - if !alias { + if !obj.IsAlias() { ndef++ } case *Func: @@ -282,14 +262,8 @@ func (check *Checker) cycleError(cycle []Object, start int) { obj := cycle[start] tname, _ := obj.(*TypeName) if tname != nil { - if check.conf.EnableAlias { - if a, ok := tname.Type().(*Alias); ok { - a.fromRHS = Typ[Invalid] - } - } else { - if tname.IsAlias() { - check.validAlias(tname, Typ[Invalid]) - } + if a, ok := tname.Type().(*Alias); ok { + a.fromRHS = Typ[Invalid] } } @@ -471,45 +445,35 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl) { versionErr = true } - if check.conf.EnableAlias { - alias := check.newAlias(obj, nil) - - // If we could not type the RHS, set it to invalid. This should - // only ever happen if we panic before setting. - defer func() { - if alias.fromRHS == nil { - alias.fromRHS = Typ[Invalid] - unalias(alias) - } - }() + alias := check.newAlias(obj, nil) - // handle type parameters even if not allowed (Alias type is supported) - if tparam0 != nil { - check.openScope(tdecl, "type parameters") - defer check.closeScope() - check.collectTypeParams(&alias.tparams, tdecl.TParamList) + // If we could not type the RHS, set it to invalid. This should + // only ever happen if we panic before setting. + defer func() { + if alias.fromRHS == nil { + alias.fromRHS = Typ[Invalid] + unalias(alias) } + }() - rhs = check.declaredType(tdecl.Type, obj) - assert(rhs != nil) - alias.fromRHS = rhs + // handle type parameters even if not allowed (Alias type is supported) + if tparam0 != nil { + check.openScope(tdecl, "type parameters") + defer check.closeScope() + check.collectTypeParams(&alias.tparams, tdecl.TParamList) + } - // spec: In an alias declaration the given type cannot be a type parameter declared in the same declaration." - // (see also go.dev/issue/75884, go.dev/issue/#75885) - if tpar, ok := rhs.(*TypeParam); ok && alias.tparams != nil && slices.Index(alias.tparams.list(), tpar) >= 0 { - check.error(tdecl.Type, MisplacedTypeParam, "cannot use type parameter declared in alias declaration as RHS") - alias.fromRHS = Typ[Invalid] - } - } else { - if !versionErr && tparam0 != nil { - check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset") - versionErr = true - } + rhs = check.declaredType(tdecl.Type, obj) + assert(rhs != nil) + alias.fromRHS = rhs - check.brokenAlias(obj) - rhs = check.typ(tdecl.Type) - check.validAlias(obj, rhs) + // spec: In an alias declaration the given type cannot be a type parameter declared in the same declaration." + // (see also go.dev/issue/75884, go.dev/issue/#75885) + if tpar, ok := rhs.(*TypeParam); ok && alias.tparams != nil && slices.Index(alias.tparams.list(), tpar) >= 0 { + check.error(tdecl.Type, MisplacedTypeParam, "cannot use type parameter declared in alias declaration as RHS") + alias.fromRHS = Typ[Invalid] } + return } @@ -520,6 +484,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl) { named := check.newNamed(obj, nil, nil) + // TODO: adjust this comment (gotypesalias) as needed if we don't need allowNilRHS anymore. // The RHS of a named N can be nil if, for example, N is defined as a cycle of aliases with // gotypesalias=0. Consider: // diff --git a/src/cmd/compile/internal/types2/issues_test.go b/src/cmd/compile/internal/types2/issues_test.go index 8ddb39987a..e564fb38fb 100644 --- a/src/cmd/compile/internal/types2/issues_test.go +++ b/src/cmd/compile/internal/types2/issues_test.go @@ -863,8 +863,7 @@ func TestIssue59944(t *testing.T) { testenv.MustHaveCGO(t) // Methods declared on aliases of cgo types are not permitted. - const src = `// -gotypesalias=1 - + const src = ` package p /* @@ -1011,8 +1010,7 @@ type A = []int type S struct{ A } ` - conf := Config{EnableAlias: true} - pkg := mustTypecheck(src, &conf, nil) + pkg := mustTypecheck(src, nil, nil) S := pkg.Scope().Lookup("S") if S == nil { @@ -1155,8 +1153,7 @@ type ( T A )` - conf := Config{EnableAlias: true} - pkg := mustTypecheck(src, &conf, nil) + pkg := mustTypecheck(src, nil, nil) T := pkg.Scope().Lookup("T").(*TypeName) got := T.String() // this must not panic (was issue) const want = "type p.T struct{}" diff --git a/src/cmd/compile/internal/types2/object.go b/src/cmd/compile/internal/types2/object.go index 5d284ee61b..87d8d70a2a 100644 --- a/src/cmd/compile/internal/types2/object.go +++ b/src/cmd/compile/internal/types2/object.go @@ -591,7 +591,7 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) { } if tname.IsAlias() { buf.WriteString(" =") - if alias, ok := typ.(*Alias); ok { // materialized? (gotypesalias=1) + if alias, ok := typ.(*Alias); ok { // materialized? TODO(gri) Do we still need this (e.g. for byte, rune)? typ = alias.fromRHS } } else if t, _ := typ.(*TypeParam); t != nil { diff --git a/src/cmd/compile/internal/types2/object_test.go b/src/cmd/compile/internal/types2/object_test.go index 4f1a653ff3..58dfc547dc 100644 --- a/src/cmd/compile/internal/types2/object_test.go +++ b/src/cmd/compile/internal/types2/object_test.go @@ -80,32 +80,31 @@ func TestEmbeddedMethod(t *testing.T) { } var testObjects = []struct { - src string - obj string - want string - alias bool // needs materialized (and possibly generic) aliases + src string + obj string + want string }{ - {"import \"io\"; var r io.Reader", "r", "var p.r io.Reader", false}, - - {"const c = 1.2", "c", "const p.c untyped float", false}, - {"const c float64 = 3.14", "c", "const p.c float64", false}, - - {"type t struct{f int}", "t", "type p.t struct{f int}", false}, - {"type t func(int)", "t", "type p.t func(int)", false}, - {"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}", false}, - {"type t[P any] struct{f P}", "t.P", "type parameter P any", false}, - {"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C", false}, - - {"type t = struct{f int}", "t", "type p.t = struct{f int}", false}, - {"type t = func(int)", "t", "type p.t = func(int)", false}, - {"type A = B; type B = int", "A", "type p.A = p.B", true}, - {"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}", true}, - {"var v int", "v", "var p.v int", false}, - - {"func f(int) string", "f", "func p.f(int) string", false}, - {"func g[P any](x P){}", "g", "func p.g[P any](x P)", false}, - {"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}", false}, - {"", "any", "type any = interface{}", false}, + {"import \"io\"; var r io.Reader", "r", "var p.r io.Reader"}, + + {"const c = 1.2", "c", "const p.c untyped float"}, + {"const c float64 = 3.14", "c", "const p.c float64"}, + + {"type t struct{f int}", "t", "type p.t struct{f int}"}, + {"type t func(int)", "t", "type p.t func(int)"}, + {"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}"}, + {"type t[P any] struct{f P}", "t.P", "type parameter P any"}, + {"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C"}, + + {"type t = struct{f int}", "t", "type p.t = struct{f int}"}, + {"type t = func(int)", "t", "type p.t = func(int)"}, + {"type A = B; type B = int", "A", "type p.A = p.B"}, + {"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}"}, + {"var v int", "v", "var p.v int"}, + + {"func f(int) string", "f", "func p.f(int) string"}, + {"func g[P any](x P){}", "g", "func p.g[P any](x P)"}, + {"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}"}, + {"", "any", "type any = interface{}"}, } func TestObjectString(t *testing.T) { @@ -114,8 +113,7 @@ func TestObjectString(t *testing.T) { for i, test := range testObjects { t.Run(fmt.Sprint(i), func(t *testing.T) { src := "package p; " + test.src - conf := Config{Error: func(error) {}, Importer: defaultImporter(), EnableAlias: test.alias} - pkg, err := typecheck(src, &conf, nil) + pkg, err := typecheck(src, nil, nil) if err != nil { t.Fatalf("%s: %s", src, err) } diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go index 2418de5268..f075f5447f 100644 --- a/src/cmd/compile/internal/types2/resolver.go +++ b/src/cmd/compile/internal/types2/resolver.go @@ -646,13 +646,12 @@ func (check *Checker) packageObjects() { } } - if false && check.conf.EnableAlias { - // With Alias nodes we can process declarations in any order. + if false { + // TODO: determine if we can enable this code now or + // if there are still problems with cycles and + // aliases. // - // TODO(adonovan): unfortunately, Alias nodes - // (GODEBUG=gotypesalias=1) don't entirely resolve - // problems with cycles. For example, in - // GOROOT/test/typeparam/issue50259.go, + // For example, in GOROOT/test/typeparam/issue50259.go, // // type T[_ any] struct{} // type A T[B] @@ -667,7 +666,7 @@ func (check *Checker) packageObjects() { check.objDecl(obj) } } else { - // Without Alias nodes, we process non-alias type declarations first, followed by + // To avoid problems with cycles, process non-alias type declarations first, followed by // alias declarations, and then everything else. This appears to avoid most situations // where the type of an alias is needed before it is available. // There may still be cases where this is not good enough (see also go.dev/issue/25838). diff --git a/src/cmd/compile/internal/types2/scope.go b/src/cmd/compile/internal/types2/scope.go index 10c624be2e..90f52a7737 100644 --- a/src/cmd/compile/internal/types2/scope.go +++ b/src/cmd/compile/internal/types2/scope.go @@ -67,21 +67,7 @@ func (s *Scope) Child(i int) *Scope { return s.children[i] } // Lookup returns the object in scope s with the given name if such an // object exists; otherwise the result is nil. -func (s *Scope) Lookup(name string) Object { - obj := resolve(name, s.elems[name]) - // Hijack Lookup for "any": with gotypesalias=1, we want the Universe to - // return an Alias for "any", and with gotypesalias=0 we want to return - // the legacy representation of aliases. - // - // This is rather tricky, but works out after auditing of the usage of - // s.elems. The only external API to access scope elements is Lookup. - // - // TODO: remove this once gotypesalias=0 is no longer supported. - if obj == universeAnyAlias && !aliasAny() { - return universeAnyNoAlias - } - return obj -} +func (s *Scope) Lookup(name string) Object { return resolve(name, s.elems[name]) } // lookupIgnoringCase returns the objects in scope s whose names match // the given name ignoring case. If exported is set, only exported names diff --git a/src/cmd/compile/internal/types2/stdlib_test.go b/src/cmd/compile/internal/types2/stdlib_test.go index ee49bbddfa..a85e66a363 100644 --- a/src/cmd/compile/internal/types2/stdlib_test.go +++ b/src/cmd/compile/internal/types2/stdlib_test.go @@ -332,10 +332,6 @@ func TestStdFixed(t *testing.T) { "issue49814.go", // go/types does not have constraints on array size "issue56103.go", // anonymous interface cycles; will be a type checker error in 1.22 "issue52697.go", // types2 does not have constraints on stack size - "issue68054.go", // this test requires GODEBUG=gotypesalias=1 - "issue68580.go", // this test requires GODEBUG=gotypesalias=1 - "issue73309.go", // this test requires GODEBUG=gotypesalias=1 - "issue73309b.go", // this test requires GODEBUG=gotypesalias=1 // These tests requires runtime/cgo.Incomplete, which is only available on some platforms. // However, types2 does not know about build constraints. @@ -402,8 +398,7 @@ func typecheckFiles(path string, filenames []string, importer Importer) (*Packag Error: func(err error) { errs = append(errs, err) }, - Importer: importer, - EnableAlias: true, + Importer: importer, } info := Info{Uses: make(map[*syntax.Name]Object)} pkg, _ := conf.Check(path, files, &info) diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go index e68f6a2886..e635b38527 100644 --- a/src/cmd/compile/internal/types2/typestring.go +++ b/src/cmd/compile/internal/types2/typestring.go @@ -211,14 +211,6 @@ func (w *typeWriter) typ(typ Type) { case *Interface: if w.ctxt == nil { - if t == universeAnyAlias.Type().Underlying() { - // When not hashing, we can try to improve type strings by writing "any" - // for a type that is pointer-identical to universeAny. - // TODO(rfindley): this logic should not be necessary with - // gotypesalias=1. Remove once that is always the case. - w.string("any") - break - } if t == asNamed(universeComparable.Type()).underlying { w.string("interface{comparable}") break diff --git a/src/cmd/compile/internal/types2/typestring_test.go b/src/cmd/compile/internal/types2/typestring_test.go index c2be40da29..fe787771e3 100644 --- a/src/cmd/compile/internal/types2/typestring_test.go +++ b/src/cmd/compile/internal/types2/typestring_test.go @@ -82,10 +82,10 @@ var independentTestTypes = []testEntry{ dup(`interface{String() string; m(int) float32}`), dup("interface{int | float32 | complex128}"), dup("interface{int | ~float32 | ~complex128}"), - dup("any"), dup("interface{comparable}"), - {"comparable", "interface{comparable}"}, {"error", "interface{Error() string}"}, + {"any", "interface{}"}, + {"comparable", "interface{comparable}"}, // maps dup("map[string]int"), diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go index 7d5932eec1..ac81b838de 100644 --- a/src/cmd/compile/internal/types2/typexpr.go +++ b/src/cmd/compile/internal/types2/typexpr.go @@ -30,14 +30,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, wantType bool) { check.errorf(e, UndeclaredName, "undefined: %s", e.Value) } return - case universeComparable: - if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Value) { - return // avoid follow-on errors - } - } - // Because the representation of any depends on gotypesalias, we don't check - // pointer identity here. - if obj.Name() == "any" && obj.Parent() == Universe { + case universeAny, universeComparable: if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Value) { return // avoid follow-on errors } @@ -109,10 +102,6 @@ func (check *Checker) ident(x *operand, e *syntax.Name, wantType bool) { x.mode = constant_ case *TypeName: - if !check.conf.EnableAlias && check.isBrokenAlias(obj) { - check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name) - return - } x.mode = typexpr case *Var: diff --git a/src/cmd/compile/internal/types2/universe.go b/src/cmd/compile/internal/types2/universe.go index 1ecef97d51..6a649843d1 100644 --- a/src/cmd/compile/internal/types2/universe.go +++ b/src/cmd/compile/internal/types2/universe.go @@ -24,9 +24,8 @@ var ( universeBool Type universeByte Type // uint8 alias, but has name "byte" universeRune Type // int32 alias, but has name "rune" - universeAnyNoAlias *TypeName - universeAnyAlias *TypeName universeError Type + universeAny Object universeComparable Object ) @@ -76,44 +75,15 @@ func defPredeclaredTypes() { for _, t := range Typ { def(NewTypeName(nopos, nil, t.name, t)) } + for _, t := range basicAliases { def(NewTypeName(nopos, nil, t.name, t)) } - // type any = interface{} - // - // Implement two representations of any: one for the legacy gotypesalias=0, - // and one for gotypesalias=1. This is necessary for consistent - // representation of interface aliases during type checking, and is - // implemented via hijacking [Scope.Lookup] for the [Universe] scope. - // - // Both representations use the same distinguished pointer for their RHS - // interface type, allowing us to detect any (even with the legacy - // representation), and format it as "any" rather than interface{}, which - // clarifies user-facing error messages significantly. - // - // TODO(rfindley): once the gotypesalias GODEBUG variable is obsolete (and we - // consistently use the Alias node), we should be able to clarify user facing - // error messages without using a distinguished pointer for the any - // interface. - { - universeAnyNoAlias = NewTypeName(nopos, nil, "any", &Interface{complete: true, tset: &topTypeSet}) - // ensure that the any TypeName reports a consistent Parent, after - // hijacking Universe.Lookup with gotypesalias=0. - universeAnyNoAlias.setParent(Universe) - - // It shouldn't matter which representation of any is actually inserted - // into the Universe, but we lean toward the future and insert the Alias - // representation. - universeAnyAlias = NewTypeName(nopos, nil, "any", nil) - _ = NewAlias(universeAnyAlias, universeAnyNoAlias.Type().Underlying()) // Link TypeName and Alias - def(universeAnyAlias) - } - // type error interface{ Error() string } { obj := NewTypeName(nopos, nil, "error", nil) - typ := (*Checker)(nil).newNamed(obj, nil, nil) + typ := NewNamed(obj, nil, nil) // error.Error() string recv := newVar(RecvVar, nopos, nil, "", typ) @@ -130,16 +100,17 @@ func defPredeclaredTypes() { def(obj) } + // type any = interface{} + { + obj := NewTypeName(nopos, nil, "any", nil) + NewAlias(obj, &emptyInterface) + def(obj) + } + // type comparable interface{} // marked as comparable { obj := NewTypeName(nopos, nil, "comparable", nil) - typ := (*Checker)(nil).newNamed(obj, nil, nil) - - // interface{} // marked as comparable - ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}} - - typ.fromRHS = ityp - typ.Underlying() + NewNamed(obj, &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}}, nil) def(obj) } } @@ -278,6 +249,7 @@ func init() { universeByte = Universe.Lookup("byte").Type() universeRune = Universe.Lookup("rune").Type() universeError = Universe.Lookup("error").Type() + universeAny = Universe.Lookup("any") universeComparable = Universe.Lookup("comparable") } diff --git a/src/go/internal/gcimporter/ureader.go b/src/go/internal/gcimporter/ureader.go index 5ce97aad3a..0db06e6359 100644 --- a/src/go/internal/gcimporter/ureader.go +++ b/src/go/internal/gcimporter/ureader.go @@ -7,7 +7,6 @@ package gcimporter import ( "go/token" "go/types" - "internal/godebug" "internal/pkgbits" "slices" "strings" @@ -678,15 +677,8 @@ func pkgScope(pkg *types.Package) *types.Scope { // newAliasTypeName returns a new TypeName, with a materialized *types.Alias if supported. func newAliasTypeName(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { - // When GODEBUG=gotypesalias=1 or unset, the Type() of the return value is a - // *types.Alias. Copied from x/tools/internal/aliases.NewAlias. - switch godebug.New("gotypesalias").Value() { - case "", "1": - tname := types.NewTypeName(pos, pkg, name, nil) - a := types.NewAlias(tname, rhs) // form TypeName -> Alias cycle - a.SetTypeParams(tparams) - return tname - } - assert(len(tparams) == 0) - return types.NewTypeName(pos, pkg, name, rhs) + tname := types.NewTypeName(pos, pkg, name, nil) + a := types.NewAlias(tname, rhs) // form TypeName -> Alias cycle + a.SetTypeParams(tparams) + return tname } diff --git a/src/go/types/alias.go b/src/go/types/alias.go index a2eeb3afac..4566ff23b1 100644 --- a/src/go/types/alias.go +++ b/src/go/types/alias.go @@ -24,24 +24,6 @@ import ( // // Like a defined ([Named]) type, an alias type has a name. // Use the [Alias.Obj] method to access its [TypeName] object. -// -// Historically, Alias types were not materialized so that, in the example -// above, A's type was represented by a Basic (int), not an Alias -// whose [Alias.Rhs] is int. But Go 1.24 allows you to declare an -// alias type with type parameters or arguments: -// -// type Set[K comparable] = map[K]bool -// s := make(Set[String]) -// -// and this requires that Alias types be materialized. Use the -// [Alias.TypeParams] and [Alias.TypeArgs] methods to access them. -// -// To ease the transition, the Alias type was introduced in go1.22, -// but the type-checker would not construct values of this type unless -// the GODEBUG=gotypesalias=1 environment variable was provided. -// Starting in go1.23, this variable is enabled by default. -// This setting also causes the predeclared type "any" to be -// represented as an Alias, not a bare [Interface]. type Alias struct { obj *TypeName // corresponding declared alias object orig *Alias // original, uninstantiated alias diff --git a/src/go/types/alias_test.go b/src/go/types/alias_test.go index aa12336e21..007f0c2999 100644 --- a/src/go/types/alias_test.go +++ b/src/go/types/alias_test.go @@ -13,8 +13,6 @@ import ( ) func TestIssue74181(t *testing.T) { - t.Setenv("GODEBUG", "gotypesalias=1") - src := `package p type AB = A[B] @@ -56,8 +54,6 @@ type A[T any] struct{}` } func TestPartialTypeCheckUndeclaredAliasPanic(t *testing.T) { - t.Setenv("GODEBUG", "gotypesalias=1") - src := `package p type A = B // undeclared` diff --git a/src/go/types/api.go b/src/go/types/api.go index 01fccbd649..cb6972992e 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -186,16 +186,6 @@ type Config struct { // of an error message. ErrorURL must be a format string containing // exactly one "%s" format, e.g. "[go.dev/e/%s]". _ErrorURL string - - // If EnableAlias is set, alias declarations produce an Alias type. Otherwise - // the alias information is only in the type name, which points directly to - // the actual (aliased) type. - // - // This setting must not differ among concurrent type-checking operations, - // since it affects the behavior of Universe.Lookup("any"). - // - // This flag will eventually be removed (with Go 1.24 at the earliest). - _EnableAlias bool } // Linkname for use from srcimporter. diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go index b5f9cbbed6..e11ff39de3 100644 --- a/src/go/types/api_test.go +++ b/src/go/types/api_test.go @@ -2993,7 +2993,6 @@ func TestTooNew(t *testing.T) { // This is a regression test for #66704. func TestUnaliasTooSoonInCycle(t *testing.T) { - setGotypesalias(t, true) const src = `package a var x T[B] // this appears to cause Unalias to be called on B while still Invalid @@ -3012,7 +3011,6 @@ type B = T[A] } func TestAlias_Rhs(t *testing.T) { - setGotypesalias(t, true) const src = `package p type A = B @@ -3029,51 +3027,6 @@ type C = int } } -// Test the hijacking described of "any" described in golang/go#66921, for type -// checking. -func TestAnyHijacking_Check(t *testing.T) { - for _, enableAlias := range []bool{false, true} { - t.Run(fmt.Sprintf("EnableAlias=%t", enableAlias), func(t *testing.T) { - setGotypesalias(t, enableAlias) - var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() - pkg := mustTypecheck("package p; var x any", nil, nil) - x := pkg.Scope().Lookup("x") - if _, gotAlias := x.Type().(*Alias); gotAlias != enableAlias { - t.Errorf(`Lookup("x").Type() is %T: got Alias: %t, want %t`, x.Type(), gotAlias, enableAlias) - } - }() - } - wg.Wait() - }) - } -} - -// Test the hijacking described of "any" described in golang/go#66921, for -// Scope.Lookup outside of type checking. -func TestAnyHijacking_Lookup(t *testing.T) { - for _, enableAlias := range []bool{false, true} { - t.Run(fmt.Sprintf("EnableAlias=%t", enableAlias), func(t *testing.T) { - setGotypesalias(t, enableAlias) - a := Universe.Lookup("any") - if _, gotAlias := a.Type().(*Alias); gotAlias != enableAlias { - t.Errorf(`Lookup("x").Type() is %T: got Alias: %t, want %t`, a.Type(), gotAlias, enableAlias) - } - }) - } -} - -func setGotypesalias(t *testing.T, enable bool) { - if enable { - t.Setenv("GODEBUG", "gotypesalias=1") - } else { - t.Setenv("GODEBUG", "gotypesalias=0") - } -} - // TestVersionIssue69477 is a regression test for issue #69477, // in which the type checker would panic while attempting // to compute which file it is "in" based on syntax position. diff --git a/src/go/types/check.go b/src/go/types/check.go index 638b1f6fcc..061dae7a0a 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -11,10 +11,8 @@ import ( "go/ast" "go/constant" "go/token" - "internal/godebug" . "internal/types/errors" "os" - "sync/atomic" ) // nopos, noposn indicate an unknown position @@ -27,42 +25,6 @@ const debug = false // leave on during development // position tracing for panics during type checking const tracePos = true -// gotypesalias controls the use of Alias types. -// As of Apr 16 2024 they are used by default. -// To disable their use, set GODEBUG to gotypesalias=0. -// This GODEBUG flag will be removed in the near future (tentatively Go 1.24). -var gotypesalias = godebug.New("gotypesalias") - -// _aliasAny changes the behavior of [Scope.Lookup] for "any" in the -// [Universe] scope. -// -// This is necessary because while Alias creation is controlled by -// [Config._EnableAlias], based on the gotypealias variable, the representation -// of "any" is a global. In [Scope.Lookup], we select this global -// representation based on the result of [aliasAny], but as a result need to -// guard against this behavior changing during the type checking pass. -// Therefore we implement the following rule: any number of goroutines can type -// check concurrently with the same EnableAlias value, but if any goroutine -// tries to type check concurrently with a different EnableAlias value, we -// panic. -// -// To achieve this, _aliasAny is a state machine: -// -// 0: no type checking is occurring -// negative: type checking is occurring without _EnableAlias set -// positive: type checking is occurring with _EnableAlias set -var _aliasAny int32 - -func aliasAny() bool { - v := gotypesalias.Value() - useAlias := v != "0" - inuse := atomic.LoadInt32(&_aliasAny) - if inuse != 0 && useAlias != (inuse > 0) { - panic(fmt.Sprintf("gotypealias mutated during type checking, gotypesalias=%s, inuse=%d", v, inuse)) - } - return useAlias -} - // exprInfo stores information about an untyped expression. type exprInfo struct { isLhs bool // expression is lhs operand of a shift with delayed type-check @@ -220,34 +182,6 @@ func (check *Checker) addDeclDep(to Object) { from.addDep(to) } -// Note: The following three alias-related functions are only used -// when Alias types are not enabled. - -// brokenAlias records that alias doesn't have a determined type yet. -// It also sets alias.typ to Typ[Invalid]. -// Not used if check.conf._EnableAlias is set. -func (check *Checker) brokenAlias(alias *TypeName) { - assert(!check.conf._EnableAlias) - if check.brokenAliases == nil { - check.brokenAliases = make(map[*TypeName]bool) - } - check.brokenAliases[alias] = true - alias.typ = Typ[Invalid] -} - -// validAlias records that alias has the valid type typ (possibly Typ[Invalid]). -func (check *Checker) validAlias(alias *TypeName, typ Type) { - assert(!check.conf._EnableAlias) - delete(check.brokenAliases, alias) - alias.typ = typ -} - -// isBrokenAlias reports whether alias doesn't have a determined type yet. -func (check *Checker) isBrokenAlias(alias *TypeName) bool { - assert(!check.conf._EnableAlias) - return check.brokenAliases[alias] -} - func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) { m := check.untyped if m == nil { @@ -316,9 +250,6 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch // // (previously, pkg.goVersion was mutated here: go.dev/issue/61212) - // In go/types, conf._EnableAlias is controlled by gotypesalias. - conf._EnableAlias = gotypesalias.Value() != "0" - return &Checker{ conf: conf, ctxt: conf.Context, @@ -497,20 +428,6 @@ func (check *Checker) Files(files []*ast.File) (err error) { // syntax is properly type annotated even in a package containing // errors. func (check *Checker) checkFiles(files []*ast.File) { - // Ensure that _EnableAlias is consistent among concurrent type checking - // operations. See the documentation of [_aliasAny] for details. - if check.conf._EnableAlias { - if atomic.AddInt32(&_aliasAny, 1) <= 0 { - panic("EnableAlias set while !EnableAlias type checking is ongoing") - } - defer atomic.AddInt32(&_aliasAny, -1) - } else { - if atomic.AddInt32(&_aliasAny, -1) >= 0 { - panic("!EnableAlias set while EnableAlias type checking is ongoing") - } - defer atomic.AddInt32(&_aliasAny, 1) - } - print := func(msg string) { if check.conf._Trace { fmt.Println() diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index 44e4fd0104..fa84ea6070 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -123,8 +123,6 @@ func parseFlags(src []byte, flags *flag.FlagSet) error { // testFiles type-checks the package consisting of the given files, and // compares the resulting errors with the ERROR annotations in the source. -// Except for manual tests, each package is type-checked twice, once without -// use of Alias types, and once with Alias types. // // The srcs slice contains the file content for the files named in the // filenames slice. The colDelta parameter specifies the tolerance for position @@ -133,15 +131,6 @@ func parseFlags(src []byte, flags *flag.FlagSet) error { // // If provided, opts may be used to mutate the Config before type-checking. func testFiles(t *testing.T, filenames []string, srcs [][]byte, manual bool, opts ...func(*Config)) { - // Alias types are enabled by default - testFilesImpl(t, filenames, srcs, manual, opts...) - if !manual { - t.Setenv("GODEBUG", "gotypesalias=0") - testFilesImpl(t, filenames, srcs, manual, opts...) - } -} - -func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, manual bool, opts ...func(*Config)) { if len(filenames) == 0 { t.Fatal("no source files") } @@ -185,12 +174,11 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, manual bool, } // apply flag setting (overrides custom configuration) - var goexperiment, gotypesalias string + var goexperiment string flags := flag.NewFlagSet("", flag.PanicOnError) flags.StringVar(&conf.GoVersion, "lang", "", "") flags.StringVar(&goexperiment, "goexperiment", "", "") flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "") - flags.StringVar(&gotypesalias, "gotypesalias", "", "") if err := parseFlags(srcs[0], flags); err != nil { t.Fatal(err) } @@ -200,11 +188,6 @@ func testFilesImpl(t *testing.T, filenames []string, srcs [][]byte, manual bool, defer revert() } - // By default, gotypesalias is not set. - if gotypesalias != "" { - t.Setenv("GODEBUG", "gotypesalias="+gotypesalias) - } - // Provide Config.Info with all maps so that info recording is tested. info := Info{ Types: make(map[ast.Expr]TypeAndValue), diff --git a/src/go/types/decl.go b/src/go/types/decl.go index 80b8c20655..576424f608 100644 --- a/src/go/types/decl.go +++ b/src/go/types/decl.go @@ -201,26 +201,7 @@ loop: break loop } - // Determine if the type name is an alias or not. For - // package-level objects, use the object map which - // provides syntactic information (which doesn't rely - // on the order in which the objects are set up). For - // local objects, we can rely on the order, so use - // the object's predicate. - // TODO(gri) It would be less fragile to always access - // the syntactic information. We should consider storing - // this information explicitly in the object. - var alias bool - if check.conf._EnableAlias { - alias = obj.IsAlias() - } else { - if d := check.objMap[obj]; d != nil { - alias = d.tdecl.Assign.IsValid() // package-level object - } else { - alias = obj.IsAlias() // function local object - } - } - if !alias { + if !obj.IsAlias() { ndef++ } case *Func: @@ -283,14 +264,8 @@ func (check *Checker) cycleError(cycle []Object, start int) { obj := cycle[start] tname, _ := obj.(*TypeName) if tname != nil { - if check.conf._EnableAlias { - if a, ok := tname.Type().(*Alias); ok { - a.fromRHS = Typ[Invalid] - } - } else { - if tname.IsAlias() { - check.validAlias(tname, Typ[Invalid]) - } + if a, ok := tname.Type().(*Alias); ok { + a.fromRHS = Typ[Invalid] } } @@ -546,52 +521,35 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec) { versionErr = true } - if check.conf._EnableAlias { - alias := check.newAlias(obj, nil) - - // If we could not type the RHS, set it to invalid. This should - // only ever happen if we panic before setting. - defer func() { - if alias.fromRHS == nil { - alias.fromRHS = Typ[Invalid] - unalias(alias) - } - }() + alias := check.newAlias(obj, nil) - // handle type parameters even if not allowed (Alias type is supported) - if tparam0 != nil { - check.openScope(tdecl, "type parameters") - defer check.closeScope() - check.collectTypeParams(&alias.tparams, tdecl.TypeParams) + // If we could not type the RHS, set it to invalid. This should + // only ever happen if we panic before setting. + defer func() { + if alias.fromRHS == nil { + alias.fromRHS = Typ[Invalid] + unalias(alias) } + }() - rhs = check.declaredType(tdecl.Type, obj) - assert(rhs != nil) - alias.fromRHS = rhs + // handle type parameters even if not allowed (Alias type is supported) + if tparam0 != nil { + check.openScope(tdecl, "type parameters") + defer check.closeScope() + check.collectTypeParams(&alias.tparams, tdecl.TypeParams) + } - // spec: In an alias declaration the given type cannot be a type parameter declared in the same declaration." - // (see also go.dev/issue/75884, go.dev/issue/#75885) - if tpar, ok := rhs.(*TypeParam); ok && alias.tparams != nil && slices.Index(alias.tparams.list(), tpar) >= 0 { - check.error(tdecl.Type, MisplacedTypeParam, "cannot use type parameter declared in alias declaration as RHS") - alias.fromRHS = Typ[Invalid] - } - } else { - // With Go1.23, the default behavior is to use Alias nodes, - // reflected by check.enableAlias. Signal non-default behavior. - // - // TODO(gri) Testing runs tests in both modes. Do we need to exclude - // tracking of non-default behavior for tests? - gotypesalias.IncNonDefault() - - if !versionErr && tparam0 != nil { - check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset") - versionErr = true - } + rhs = check.declaredType(tdecl.Type, obj) + assert(rhs != nil) + alias.fromRHS = rhs - check.brokenAlias(obj) - rhs = check.typ(tdecl.Type) - check.validAlias(obj, rhs) + // spec: In an alias declaration the given type cannot be a type parameter declared in the same declaration." + // (see also go.dev/issue/75884, go.dev/issue/#75885) + if tpar, ok := rhs.(*TypeParam); ok && alias.tparams != nil && slices.Index(alias.tparams.list(), tpar) >= 0 { + check.error(tdecl.Type, MisplacedTypeParam, "cannot use type parameter declared in alias declaration as RHS") + alias.fromRHS = Typ[Invalid] } + return } diff --git a/src/go/types/eval_test.go b/src/go/types/eval_test.go index f7f0da0db9..fd62b7ab88 100644 --- a/src/go/types/eval_test.go +++ b/src/go/types/eval_test.go @@ -12,7 +12,6 @@ import ( "go/parser" "go/token" "go/types" - "internal/godebug" "internal/testenv" "strings" "testing" @@ -174,14 +173,8 @@ func TestEvalPos(t *testing.T) { t.Fatalf("could not parse file %d: %s", i, err) } - // Materialized aliases give a different (better) - // result for the final test, so skip it for now. - // TODO(adonovan): reenable when gotypesalias=1 is the default. - switch gotypesalias.Value() { - case "", "1": - if strings.Contains(src, "interface{R}.Read") { - continue - } + if strings.Contains(src, "interface{R}.Read") { + continue } files = append(files, file) @@ -207,9 +200,6 @@ func TestEvalPos(t *testing.T) { } } -// gotypesalias controls the use of Alias types. -var gotypesalias = godebug.New("gotypesalias") - // split splits string s at the first occurrence of s, trimming spaces. func split(s, sep string) (string, string) { before, after, _ := strings.Cut(s, sep) diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go index 6388dcf687..3649189042 100644 --- a/src/go/types/issues_test.go +++ b/src/go/types/issues_test.go @@ -875,8 +875,7 @@ func TestIssue59944(t *testing.T) { testenv.MustHaveCGO(t) // Methods declared on aliases of cgo types are not permitted. - const src = `// -gotypesalias=1 - + const src = ` package p /* @@ -1024,7 +1023,6 @@ type A = []int type S struct{ A } ` - t.Setenv("GODEBUG", "gotypesalias=1") pkg := mustTypecheck(src, nil, nil) S := pkg.Scope().Lookup("S") @@ -1168,7 +1166,6 @@ type ( T A )` - t.Setenv("GODEBUG", "gotypesalias=1") pkg := mustTypecheck(src, nil, nil) T := pkg.Scope().Lookup("T").(*TypeName) got := T.String() // this must not panic (was issue) diff --git a/src/go/types/object.go b/src/go/types/object.go index e12bf7285a..46cc830bce 100644 --- a/src/go/types/object.go +++ b/src/go/types/object.go @@ -594,7 +594,7 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) { } if tname.IsAlias() { buf.WriteString(" =") - if alias, ok := typ.(*Alias); ok { // materialized? (gotypesalias=1) + if alias, ok := typ.(*Alias); ok { // materialized? TODO(gri) Do we still need this (e.g. for byte, rune)? typ = alias.fromRHS } } else if t, _ := typ.(*TypeParam); t != nil { diff --git a/src/go/types/object_test.go b/src/go/types/object_test.go index fc165fb7a0..3ae97149d8 100644 --- a/src/go/types/object_test.go +++ b/src/go/types/object_test.go @@ -80,32 +80,31 @@ func TestEmbeddedMethod(t *testing.T) { } var testObjects = []struct { - src string - obj string - want string - alias bool // needs materialized (and possibly generic) aliases + src string + obj string + want string }{ - {"import \"io\"; var r io.Reader", "r", "var p.r io.Reader", false}, - - {"const c = 1.2", "c", "const p.c untyped float", false}, - {"const c float64 = 3.14", "c", "const p.c float64", false}, - - {"type t struct{f int}", "t", "type p.t struct{f int}", false}, - {"type t func(int)", "t", "type p.t func(int)", false}, - {"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}", false}, - {"type t[P any] struct{f P}", "t.P", "type parameter P any", false}, - {"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C", false}, - - {"type t = struct{f int}", "t", "type p.t = struct{f int}", false}, - {"type t = func(int)", "t", "type p.t = func(int)", false}, - {"type A = B; type B = int", "A", "type p.A = p.B", true}, - {"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}", true}, - {"var v int", "v", "var p.v int", false}, - - {"func f(int) string", "f", "func p.f(int) string", false}, - {"func g[P any](x P){}", "g", "func p.g[P any](x P)", false}, - {"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}", false}, - {"", "any", "type any = interface{}", false}, + {"import \"io\"; var r io.Reader", "r", "var p.r io.Reader"}, + + {"const c = 1.2", "c", "const p.c untyped float"}, + {"const c float64 = 3.14", "c", "const p.c float64"}, + + {"type t struct{f int}", "t", "type p.t struct{f int}"}, + {"type t func(int)", "t", "type p.t func(int)"}, + {"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}"}, + {"type t[P any] struct{f P}", "t.P", "type parameter P any"}, + {"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C"}, + + {"type t = struct{f int}", "t", "type p.t = struct{f int}"}, + {"type t = func(int)", "t", "type p.t = func(int)"}, + {"type A = B; type B = int", "A", "type p.A = p.B"}, + {"type A[P ~int] = struct{}", "A", "type p.A[P ~int] = struct{}"}, + {"var v int", "v", "var p.v int"}, + + {"func f(int) string", "f", "func p.f(int) string"}, + {"func g[P any](x P){}", "g", "func p.g[P any](x P)"}, + {"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}"}, + {"", "any", "type any = interface{}"}, } func TestObjectString(t *testing.T) { @@ -113,10 +112,6 @@ func TestObjectString(t *testing.T) { for i, test := range testObjects { t.Run(fmt.Sprint(i), func(t *testing.T) { - if test.alias { - t.Setenv("GODEBUG", "gotypesalias=1") - } - src := "package p; " + test.src pkg, err := typecheck(src, nil, nil) if err != nil { diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index 52576db2bd..4f7dfc19fd 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -641,13 +641,12 @@ func (check *Checker) packageObjects() { } } - if false && check.conf._EnableAlias { - // With Alias nodes we can process declarations in any order. + if false { + // TODO: determine if we can enable this code now or + // if there are still problems with cycles and + // aliases. // - // TODO(adonovan): unfortunately, Alias nodes - // (GODEBUG=gotypesalias=1) don't entirely resolve - // problems with cycles. For example, in - // GOROOT/test/typeparam/issue50259.go, + // For example, in GOROOT/test/typeparam/issue50259.go, // // type T[_ any] struct{} // type A T[B] @@ -662,7 +661,7 @@ func (check *Checker) packageObjects() { check.objDecl(obj) } } else { - // Without Alias nodes, we process non-alias type declarations first, followed by + // To avoid problems with cycles, we process non-alias type declarations first, followed by // alias declarations, and then everything else. This appears to avoid most situations // where the type of an alias is needed before it is available. // There may still be cases where this is not good enough (see also go.dev/issue/25838). diff --git a/src/go/types/scope.go b/src/go/types/scope.go index e44b097dc5..3c59883e5c 100644 --- a/src/go/types/scope.go +++ b/src/go/types/scope.go @@ -70,21 +70,7 @@ func (s *Scope) Child(i int) *Scope { return s.children[i] } // Lookup returns the object in scope s with the given name if such an // object exists; otherwise the result is nil. -func (s *Scope) Lookup(name string) Object { - obj := resolve(name, s.elems[name]) - // Hijack Lookup for "any": with gotypesalias=1, we want the Universe to - // return an Alias for "any", and with gotypesalias=0 we want to return - // the legacy representation of aliases. - // - // This is rather tricky, but works out after auditing of the usage of - // s.elems. The only external API to access scope elements is Lookup. - // - // TODO: remove this once gotypesalias=0 is no longer supported. - if obj == universeAnyAlias && !aliasAny() { - return universeAnyNoAlias - } - return obj -} +func (s *Scope) Lookup(name string) Object { return resolve(name, s.elems[name]) } // lookupIgnoringCase returns the objects in scope s whose names match // the given name ignoring case. If exported is set, only exported names diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go index 6b72bbf44d..7830029fb2 100644 --- a/src/go/types/stdlib_test.go +++ b/src/go/types/stdlib_test.go @@ -332,10 +332,6 @@ func TestStdFixed(t *testing.T) { "issue49814.go", // go/types does not have constraints on array size "issue56103.go", // anonymous interface cycles; will be a type checker error in 1.22 "issue52697.go", // go/types does not have constraints on stack size - "issue68054.go", // this test requires GODEBUG=gotypesalias=1 - "issue68580.go", // this test requires GODEBUG=gotypesalias=1 - "issue73309.go", // this test requires GODEBUG=gotypesalias=1 - "issue73309b.go", // this test requires GODEBUG=gotypesalias=1 // These tests requires runtime/cgo.Incomplete, which is only available on some platforms. // However, go/types does not know about build constraints. diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go index 766d2b2960..5a106c7919 100644 --- a/src/go/types/typestring.go +++ b/src/go/types/typestring.go @@ -214,14 +214,6 @@ func (w *typeWriter) typ(typ Type) { case *Interface: if w.ctxt == nil { - if t == universeAnyAlias.Type().Underlying() { - // When not hashing, we can try to improve type strings by writing "any" - // for a type that is pointer-identical to universeAny. - // TODO(rfindley): this logic should not be necessary with - // gotypesalias=1. Remove once that is always the case. - w.string("any") - break - } if t == asNamed(universeComparable.Type()).underlying { w.string("interface{comparable}") break diff --git a/src/go/types/typestring_test.go b/src/go/types/typestring_test.go index 45670b7e15..b60a6a955c 100644 --- a/src/go/types/typestring_test.go +++ b/src/go/types/typestring_test.go @@ -82,11 +82,11 @@ var independentTestTypes = []testEntry{ dup(`interface{String() string; m(int) float32}`), dup("interface{int | float32 | complex128}"), dup("interface{int | ~float32 | ~complex128}"), - dup("any"), dup("interface{comparable}"), // TODO(gri) adjust test for EvalCompositeTest - // {"comparable", "interface{comparable}"}, // {"error", "interface{Error() string}"}, + // {"any", "interface{}"}, + // {"comparable", "interface{comparable}"}, // maps dup("map[string]int"), diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 549c307487..7b9d2d3cbc 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -30,14 +30,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, wantType bool) { check.errorf(e, UndeclaredName, "undefined: %s", e.Name) } return - case universeComparable: - if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Name) { - return // avoid follow-on errors - } - } - // Because the representation of any depends on gotypesalias, we don't check - // pointer identity here. - if obj.Name() == "any" && obj.Parent() == Universe { + case universeAny, universeComparable: if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Name) { return // avoid follow-on errors } @@ -108,10 +101,6 @@ func (check *Checker) ident(x *operand, e *ast.Ident, wantType bool) { x.mode = constant_ case *TypeName: - if !check.conf._EnableAlias && check.isBrokenAlias(obj) { - check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name) - return - } x.mode = typexpr case *Var: diff --git a/src/go/types/universe.go b/src/go/types/universe.go index 8d2b99cf17..5dbef0af57 100644 --- a/src/go/types/universe.go +++ b/src/go/types/universe.go @@ -27,9 +27,8 @@ var ( universeBool Type universeByte Type // uint8 alias, but has name "byte" universeRune Type // int32 alias, but has name "rune" - universeAnyNoAlias *TypeName - universeAnyAlias *TypeName universeError Type + universeAny Object universeComparable Object ) @@ -79,44 +78,15 @@ func defPredeclaredTypes() { for _, t := range Typ { def(NewTypeName(nopos, nil, t.name, t)) } + for _, t := range basicAliases { def(NewTypeName(nopos, nil, t.name, t)) } - // type any = interface{} - // - // Implement two representations of any: one for the legacy gotypesalias=0, - // and one for gotypesalias=1. This is necessary for consistent - // representation of interface aliases during type checking, and is - // implemented via hijacking [Scope.Lookup] for the [Universe] scope. - // - // Both representations use the same distinguished pointer for their RHS - // interface type, allowing us to detect any (even with the legacy - // representation), and format it as "any" rather than interface{}, which - // clarifies user-facing error messages significantly. - // - // TODO(rfindley): once the gotypesalias GODEBUG variable is obsolete (and we - // consistently use the Alias node), we should be able to clarify user facing - // error messages without using a distinguished pointer for the any - // interface. - { - universeAnyNoAlias = NewTypeName(nopos, nil, "any", &Interface{complete: true, tset: &topTypeSet}) - // ensure that the any TypeName reports a consistent Parent, after - // hijacking Universe.Lookup with gotypesalias=0. - universeAnyNoAlias.setParent(Universe) - - // It shouldn't matter which representation of any is actually inserted - // into the Universe, but we lean toward the future and insert the Alias - // representation. - universeAnyAlias = NewTypeName(nopos, nil, "any", nil) - _ = NewAlias(universeAnyAlias, universeAnyNoAlias.Type().Underlying()) // Link TypeName and Alias - def(universeAnyAlias) - } - // type error interface{ Error() string } { obj := NewTypeName(nopos, nil, "error", nil) - typ := (*Checker)(nil).newNamed(obj, nil, nil) + typ := NewNamed(obj, nil, nil) // error.Error() string recv := newVar(RecvVar, nopos, nil, "", typ) @@ -133,16 +103,17 @@ func defPredeclaredTypes() { def(obj) } + // type any = interface{} + { + obj := NewTypeName(nopos, nil, "any", nil) + NewAlias(obj, &emptyInterface) + def(obj) + } + // type comparable interface{} // marked as comparable { obj := NewTypeName(nopos, nil, "comparable", nil) - typ := (*Checker)(nil).newNamed(obj, nil, nil) - - // interface{} // marked as comparable - ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}} - - typ.fromRHS = ityp - typ.Underlying() + NewNamed(obj, &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}}, nil) def(obj) } } @@ -281,6 +252,7 @@ func init() { universeByte = Universe.Lookup("byte").Type() universeRune = Universe.Lookup("rune").Type() universeError = Universe.Lookup("error").Type() + universeAny = Universe.Lookup("any") universeComparable = Universe.Lookup("comparable") } diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go index 87b499385a..a7c984b5e2 100644 --- a/src/internal/godebugs/table.go +++ b/src/internal/godebugs/table.go @@ -39,7 +39,6 @@ var All = []Info{ {Name: "gocachetest", Package: "cmd/go"}, {Name: "gocacheverify", Package: "cmd/go"}, {Name: "gotestjsonbuildtext", Package: "cmd/go", Changed: 24, Old: "1"}, - {Name: "gotypesalias", Package: "go/types", Changed: 23, Old: "0"}, {Name: "http2client", Package: "net/http"}, {Name: "http2debug", Package: "net/http", Opaque: true}, {Name: "http2server", Package: "net/http"}, @@ -90,6 +89,7 @@ type RemovedInfo struct { // Removed contains all GODEBUGs that we have removed. var Removed = []RemovedInfo{ {Name: "x509sha1", Removed: 24}, + {Name: "gotypesalias", Removed: 27}, } // Lookup returns the Info with the given name. diff --git a/src/internal/types/testdata/check/cycles5.go b/src/internal/types/testdata/check/cycles5.go index 9605f8ded4..40a6d9b483 100644 --- a/src/internal/types/testdata/check/cycles5.go +++ b/src/internal/types/testdata/check/cycles5.go @@ -1,5 +1,3 @@ -// -gotypesalias=0 - // Copyright 2017 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. @@ -137,7 +135,7 @@ type ( type ( a struct{ *b } b = c - c struct{ *b /* ERROR "invalid use of type alias" */ } + c struct{ *b } ) // issue #24939 @@ -147,7 +145,7 @@ type ( } M interface { - F() P // ERROR "invalid use of type alias" + F() P } P = interface { diff --git a/src/internal/types/testdata/check/cycles5a.go b/src/internal/types/testdata/check/cycles5a.go deleted file mode 100644 index a8cad50243..0000000000 --- a/src/internal/types/testdata/check/cycles5a.go +++ /dev/null @@ -1,202 +0,0 @@ -// -gotypesalias=1 - -// Copyright 2017 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 p - -import "unsafe" - -// test case from issue #18395 - -type ( - A interface { B } - B interface { C } - C interface { D; F() A } - D interface { G() B } -) - -var _ = A(nil).G // G must be found - - -// test case from issue #21804 - -type sourceBridge interface { - listVersions() ([]Version, error) -} - -type Constraint interface { - copyTo(*ConstraintMsg) -} - -type ConstraintMsg struct{} - -func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion { - return nil -} - -type Version interface { - Constraint -} - -type UnpairedVersion interface { - Version -} - -var _ Constraint = UnpairedVersion(nil) - - -// derived test case from issue #21804 - -type ( - _ interface{ m(B1) } - A1 interface{ a(D1) } - B1 interface{ A1 } - C1 interface{ B1 } - D1 interface{ C1 } -) - -var _ A1 = C1(nil) - - -// derived test case from issue #22701 - -func F(x I4) interface{} { - return x.Method() -} - -type Unused interface { - RefersToI1(a I1) -} - -type I1 interface { - I2 - I3 -} - -type I2 interface { - RefersToI4() I4 -} - -type I3 interface { - Method() interface{} -} - -type I4 interface { - I1 -} - - -// check embedding of error interface - -type Error interface{ error } - -var err Error -var _ = err.Error() - - -// more esoteric cases - -type ( - T1 interface { T2 } - T2 /* ERROR "invalid recursive type" */ T2 -) - -type ( - T3 interface { T4 } - T4 /* ERROR "invalid recursive type" */ T5 - T5 = T6 - T6 = T7 - T7 = T4 -) - - -// arbitrary code may appear inside an interface - -const n = unsafe.Sizeof(func(){}) - -type I interface { - m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte) -} - - -// test cases for varias alias cycles - -type T10 /* ERROR "invalid recursive type" */ = *T10 // issue #25141 -type T11 /* ERROR "invalid recursive type" */ = interface{ f(T11) } // issue #23139 - -// issue #18640 -type ( - aa = bb - bb struct { - *aa - } -) - -type ( - a struct{ *b } - b = c - c struct{ *b } -) - -// issue #24939 -type ( - _ interface { - M(P) - } - - M interface { - F() P - } - - P = interface { - I() M - } -) - -// issue #8699 -type T12 /* ERROR "invalid recursive type" */ [len(a12)]int -var a12 = makeArray() -func makeArray() (res T12) { return } - -// issue #20770 -var r = newReader() -func newReader() r // ERROR "r (package-level variable) is not a type" - -// variations of the theme of #8699 and #20770 -var arr /* ERROR "cycle" */ = f() -func f() [len(arr)]int - -// issue #25790 -func ff(ff /* ERROR "not a type" */ ) -func gg((gg /* ERROR "not a type" */ )) - -type T13 /* ERROR "invalid recursive type T13" */ [len(b13)]int -var b13 T13 - -func g1() [unsafe.Sizeof(g1)]int -func g2() [unsafe.Sizeof(x2)]int -var x2 = g2 - -// verify that we get the correct sizes for the functions above -// (note: assert is statically evaluated in go/types test mode) -func init() { - assert(unsafe.Sizeof(g1) == 8) - assert(unsafe.Sizeof(x2) == 8) -} - -func h() [h /* ERROR "no value" */ ()[0]]int { panic(0) } - -var c14 /* ERROR "cycle" */ T14 -type T14 [uintptr(unsafe.Sizeof(&c14))]byte - -// issue #34333 -type T15 /* ERROR "invalid recursive type T15" */ struct { - f func() T16 - b T16 -} - -type T16 struct { - T15 -} \ No newline at end of file diff --git a/src/internal/types/testdata/fixedbugs/issue46461.go b/src/internal/types/testdata/fixedbugs/issue46461.go index 454f7e8365..8bf31090b8 100644 --- a/src/internal/types/testdata/fixedbugs/issue46461.go +++ b/src/internal/types/testdata/fixedbugs/issue46461.go @@ -1,5 +1,3 @@ -// -gotypesalias=0 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue46461a.go b/src/internal/types/testdata/fixedbugs/issue46461a.go deleted file mode 100644 index 74ed6c4882..0000000000 --- a/src/internal/types/testdata/fixedbugs/issue46461a.go +++ /dev/null @@ -1,22 +0,0 @@ -// -gotypesalias=1 - -// 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 p - -// test case 1 -type T[U interface{ M() T[U] }] int - -type X int - -func (X) M() T[X] { return 0 } - -// test case 2 -type A[T interface{ A[T] }] interface{} - -// test case 3 -type A2[U interface{ A2[U] }] interface{ M() A2[U] } - -type I interface{ A2[I]; M() A2[I] } diff --git a/src/internal/types/testdata/fixedbugs/issue47968.go b/src/internal/types/testdata/fixedbugs/issue47968.go index e260c63a76..b748651428 100644 --- a/src/internal/types/testdata/fixedbugs/issue47968.go +++ b/src/internal/types/testdata/fixedbugs/issue47968.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue50729b.go b/src/internal/types/testdata/fixedbugs/issue50729b.go index bc1f4406e5..76959c2f26 100644 --- a/src/internal/types/testdata/fixedbugs/issue50729b.go +++ b/src/internal/types/testdata/fixedbugs/issue50729b.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // Copyright 2023 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. diff --git a/src/internal/types/testdata/fixedbugs/issue50779.go b/src/internal/types/testdata/fixedbugs/issue50779.go index 59c0f2d6a0..6306df65f4 100644 --- a/src/internal/types/testdata/fixedbugs/issue50779.go +++ b/src/internal/types/testdata/fixedbugs/issue50779.go @@ -1,5 +1,3 @@ -// -gotypesalias=0 - // Copyright 2022 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. @@ -17,7 +15,7 @@ type R[S any, P any] struct{} type SR = R[SS, ST] type SS interface { - NSR(any) *SR // ERROR "invalid use of type alias SR in recursive type" + NSR(any) *SR } type C interface { diff --git a/src/internal/types/testdata/fixedbugs/issue50779a.go b/src/internal/types/testdata/fixedbugs/issue50779a.go deleted file mode 100644 index d0e99058b7..0000000000 --- a/src/internal/types/testdata/fixedbugs/issue50779a.go +++ /dev/null @@ -1,25 +0,0 @@ -// -gotypesalias=1 - -// Copyright 2022 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 p - -type AC interface { - C -} - -type ST []int - -type R[S any, P any] struct{} - -type SR = R[SS, ST] - -type SS interface { - NSR(any) *SR -} - -type C interface { - NSR(any) *SR -} diff --git a/src/internal/types/testdata/fixedbugs/issue65854.go b/src/internal/types/testdata/fixedbugs/issue65854.go index 744777a94f..8fdd3ae94a 100644 --- a/src/internal/types/testdata/fixedbugs/issue65854.go +++ b/src/internal/types/testdata/fixedbugs/issue65854.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue67628.go b/src/internal/types/testdata/fixedbugs/issue67628.go index dff1bee4a0..cd45cd61b9 100644 --- a/src/internal/types/testdata/fixedbugs/issue67628.go +++ b/src/internal/types/testdata/fixedbugs/issue67628.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue67683.go b/src/internal/types/testdata/fixedbugs/issue67683.go index c9ad5f6788..fbad886331 100644 --- a/src/internal/types/testdata/fixedbugs/issue67683.go +++ b/src/internal/types/testdata/fixedbugs/issue67683.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue69576.go b/src/internal/types/testdata/fixedbugs/issue69576.go index fc436bbfd3..1bc9b4ee33 100644 --- a/src/internal/types/testdata/fixedbugs/issue69576.go +++ b/src/internal/types/testdata/fixedbugs/issue69576.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue69955.go b/src/internal/types/testdata/fixedbugs/issue69955.go index 68ddf4108c..01a5d95262 100644 --- a/src/internal/types/testdata/fixedbugs/issue69955.go +++ b/src/internal/types/testdata/fixedbugs/issue69955.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue70417.go b/src/internal/types/testdata/fixedbugs/issue70417.go index 74bdea3b8a..683df3a503 100644 --- a/src/internal/types/testdata/fixedbugs/issue70417.go +++ b/src/internal/types/testdata/fixedbugs/issue70417.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/fixedbugs/issue71198.go b/src/internal/types/testdata/fixedbugs/issue71198.go index 479f8e2b0c..f2dcc9828a 100644 --- a/src/internal/types/testdata/fixedbugs/issue71198.go +++ b/src/internal/types/testdata/fixedbugs/issue71198.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // Copyright 2025 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. diff --git a/src/internal/types/testdata/fixedbugs/issue75885.go b/src/internal/types/testdata/fixedbugs/issue75885.go index f0cf4a65ed..77f220b87a 100644 --- a/src/internal/types/testdata/fixedbugs/issue75885.go +++ b/src/internal/types/testdata/fixedbugs/issue75885.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // Copyright 2025 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. diff --git a/src/internal/types/testdata/spec/receivers.go b/src/internal/types/testdata/spec/receivers.go index 010c5511c1..0df1bfd6cc 100644 --- a/src/internal/types/testdata/spec/receivers.go +++ b/src/internal/types/testdata/spec/receivers.go @@ -1,5 +1,3 @@ -// -gotypesalias=1 - // 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. diff --git a/src/internal/types/testdata/spec/typeAliases1.23b.go b/src/internal/types/testdata/spec/typeAliases1.23.go similarity index 97% rename from src/internal/types/testdata/spec/typeAliases1.23b.go rename to src/internal/types/testdata/spec/typeAliases1.23.go index 8a09899066..061792974d 100644 --- a/src/internal/types/testdata/spec/typeAliases1.23b.go +++ b/src/internal/types/testdata/spec/typeAliases1.23.go @@ -1,4 +1,4 @@ -// -lang=go1.23 -gotypesalias=1 +// -lang=go1.23 // Copyright 2024 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/src/internal/types/testdata/spec/typeAliases1.23a.go b/src/internal/types/testdata/spec/typeAliases1.23a.go deleted file mode 100644 index 0ea21a4e32..0000000000 --- a/src/internal/types/testdata/spec/typeAliases1.23a.go +++ /dev/null @@ -1,10 +0,0 @@ -// -lang=go1.23 -gotypesalias=0 - -// 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 aliasTypes - -type _ = int -type _ /* ERROR "generic type alias requires GODEBUG=gotypesalias=1" */ [P any] = int diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go index 6b774c36f3..361e68f0b3 100644 --- a/src/runtime/metrics/doc.go +++ b/src/runtime/metrics/doc.go @@ -302,10 +302,6 @@ Below is the full list of supported metrics, ordered lexicographically. package due to a non-default GODEBUG=gotestjsonbuildtext=... setting. - /godebug/non-default-behavior/gotypesalias:events - The number of non-default behaviors executed by the go/types - package due to a non-default GODEBUG=gotypesalias=... setting. - /godebug/non-default-behavior/http2client:events The number of non-default behaviors executed by the net/http package due to a non-default GODEBUG=http2client=... setting.