// 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) *types.TypeName {
- // When GODEBUG=gotypesalias=1, the Type() of the return value is a
+ // When GODEBUG=gotypesalias=1 or unset, the Type() of the return value is a
// *types.Alias. Copied from x/tools/internal/aliases.NewAlias.
- if godebug.New("gotypesalias").Value() == "1" {
+ switch godebug.New("gotypesalias").Value() {
+ case "", "1":
tname := types.NewTypeName(pos, pkg, name, nil)
_ = types.NewAlias(tname, rhs) // form TypeName -> Alias cycle
return tname
// 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
// debugging/development support
const debug = false // leave on during development
-// gotypesalias controls the use of Alias types
+// gotypesalias controls the use of Alias types.
+// As of Apr 12 2024 it is on by default.
+// It will be removed soon.
var gotypesalias = godebug.New("gotypesalias")
// exprInfo stores information about an untyped expression.
//
// (previously, pkg.goVersion was mutated here: go.dev/issue/61212)
+ enableAlias := false
+ switch gotypesalias.Value() {
+ case "", "1":
+ enableAlias = true
+ }
+
return &Checker{
- enableAlias: gotypesalias.Value() == "1",
+ enableAlias: enableAlias,
conf: conf,
ctxt: conf.Context,
fset: fset,
// 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
//
// 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 disabled by default
- testFilesImpl(t, filenames, srcs, manual, opts...)
- if !manual {
- t.Setenv("GODEBUG", "gotypesalias=1")
- 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")
}
Unalias(alias) // resolve alias.actual
} else {
if !versionErr && tparam0 != nil {
- check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1")
+ check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset")
versionErr = true
}
// 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.
- if gotypesalias.Value() == "1" && strings.Contains(src, "interface{R}.Read") {
- continue
+ switch gotypesalias.Value() {
+ case "", "1":
+ if strings.Contains(src, "interface{R}.Read") {
+ continue
+ }
}
files = append(files, file)
type S struct{ A }
`
- t.Setenv("GODEBUG", "gotypesalias=1")
+ // t.Setenv("GODEBUG", "gotypesalias=1") // now on by default
pkg := mustTypecheck(src, nil, nil)
S := pkg.Scope().Lookup("S")
{Name: "gocachehash", Package: "cmd/go"},
{Name: "gocachetest", Package: "cmd/go"},
{Name: "gocacheverify", Package: "cmd/go"},
- {Name: "gotypesalias", Package: "go/types", Opaque: true}, // bug #66216: remove Opaque
+ {Name: "gotypesalias", Package: "go/types", Changed: 23, Old: "0", Opaque: true}, // bug #66216: remove Opaque
{Name: "http2client", Package: "net/http"},
{Name: "http2debug", Package: "net/http", Opaque: true},
{Name: "http2server", Package: "net/http"},