1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.22 6 // +build go1.22 7 8 package aliases 9 10 import ( 11 "go/ast" 12 "go/parser" 13 "go/token" 14 "go/types" 15 ) 16 17 // Alias is an alias of types.Alias. 18 type Alias = types.Alias 19 20 // Rhs returns the type on the right-hand side of the alias declaration. 21 func Rhs(alias *Alias) types.Type { 22 if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok { 23 return alias.Rhs() // go1.23+ 24 } 25 26 // go1.22's Alias didn't have the Rhs method, 27 // so Unalias is the best we can do. 28 return Unalias(alias) 29 } 30 31 // Unalias is a wrapper of types.Unalias. 32 func Unalias(t types.Type) types.Type { return types.Unalias(t) } 33 34 // newAlias is an internal alias around types.NewAlias. 35 // Direct usage is discouraged as the moment. 36 // Try to use NewAlias instead. 37 func newAlias(tname *types.TypeName, rhs types.Type) *Alias { 38 a := types.NewAlias(tname, rhs) 39 // TODO(go.dev/issue/65455): Remove kludgy workaround to set a.actual as a side-effect. 40 Unalias(a) 41 return a 42 } 43 44 // Enabled reports whether [NewAlias] should create [types.Alias] types. 45 // 46 // This function is expensive! Call it sparingly. 47 func Enabled() bool { 48 // The only reliable way to compute the answer is to invoke go/types. 49 // We don't parse the GODEBUG environment variable, because 50 // (a) it's tricky to do so in a manner that is consistent 51 // with the godebug package; in particular, a simple 52 // substring check is not good enough. The value is a 53 // rightmost-wins list of options. But more importantly: 54 // (b) it is impossible to detect changes to the effective 55 // setting caused by os.Setenv("GODEBUG"), as happens in 56 // many tests. Therefore any attempt to cache the result 57 // is just incorrect. 58 fset := token.NewFileSet() 59 f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0) 60 pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil) 61 _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias) 62 return enabled 63 } 64