go/types: add Alias.Rhs

This method returns the type on the right-hand side of an
alias declaration such as type L = R.

Fixes #66559

Change-Id: I396f2d999680ad251f47cdde20856ae20fc1c40a
Reviewed-on: https://go-review.googlesource.com/c/go/+/581615
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
diff --git a/api/next/66559.txt b/api/next/66559.txt
new file mode 100644
index 0000000..8b83bcc
--- /dev/null
+++ b/api/next/66559.txt
@@ -0,0 +1 @@
+pkg go/types, method (*Alias) Rhs() Type #66559
diff --git a/doc/next/6-stdlib/99-minor/go/types/66559.md b/doc/next/6-stdlib/99-minor/go/types/66559.md
new file mode 100644
index 0000000..fbaf391
--- /dev/null
+++ b/doc/next/6-stdlib/99-minor/go/types/66559.md
@@ -0,0 +1,3 @@
+The [Alias] type now has an [Rhs] method that returns the type on the
+right-hand side of its declaration: given `type A = B`, the `Rhs` of A
+is B. ([#66559](/issue/12345))
diff --git a/src/cmd/compile/internal/types2/alias.go b/src/cmd/compile/internal/types2/alias.go
index 030f6cd..9b7a13f 100644
--- a/src/cmd/compile/internal/types2/alias.go
+++ b/src/cmd/compile/internal/types2/alias.go
@@ -32,11 +32,9 @@
 func (a *Alias) Underlying() Type { return unalias(a).Underlying() }
 func (a *Alias) String() string   { return TypeString(a, nil) }
 
-// TODO(adonovan): uncomment when proposal #66559 is accepted.
-//
-// // Rhs returns the type R on the right-hand side of an alias
-// // declaration "type A = R", which may be another alias.
-// func (a *Alias) Rhs() Type { return a.fromRHS }
+// Rhs returns the type R on the right-hand side of an alias
+// declaration "type A = R", which may be another alias.
+func (a *Alias) Rhs() Type { return a.fromRHS }
 
 // Unalias returns t if it is not an alias type;
 // otherwise it follows t's alias chain until it
diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go
index 36d9004..029d105 100644
--- a/src/cmd/compile/internal/types2/api.go
+++ b/src/cmd/compile/internal/types2/api.go
@@ -475,10 +475,3 @@
 	pkg := NewPackage(path, "")
 	return pkg, NewChecker(conf, pkg, info).Files(files)
 }
-
-// Rhs returns the type R on the right-hand side of an alias
-// declaration "type A = R", which may be another alias.
-//
-// TODO(adonovan): move to alias.go (common with go/types) once
-// proposal #66559 is accepted.
-func (a *Alias) Rhs() Type { return a.fromRHS }
diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go
index 840a3f3..cf3c105 100644
--- a/src/cmd/compile/internal/types2/api_test.go
+++ b/src/cmd/compile/internal/types2/api_test.go
@@ -3005,3 +3005,20 @@
 		t.Errorf("Unalias(type B = T[A]) = %q, want %q", got, want)
 	}
 }
+
+func TestAlias_Rhs(t *testing.T) {
+	const src = `package p
+
+type A = B
+type B = C
+type C = int
+`
+
+	pkg := mustTypecheck(src, &Config{EnableAlias: true}, nil)
+	A := pkg.Scope().Lookup("A")
+
+	got, want := A.Type().(*Alias).Rhs().String(), "p.B"
+	if got != want {
+		t.Errorf("A.Rhs = %s, want %s", got, want)
+	}
+}
diff --git a/src/go/types/alias.go b/src/go/types/alias.go
index 963eb92..56d2ad0 100644
--- a/src/go/types/alias.go
+++ b/src/go/types/alias.go
@@ -35,11 +35,9 @@
 func (a *Alias) Underlying() Type { return unalias(a).Underlying() }
 func (a *Alias) String() string   { return TypeString(a, nil) }
 
-// TODO(adonovan): uncomment when proposal #66559 is accepted.
-//
-// // Rhs returns the type R on the right-hand side of an alias
-// // declaration "type A = R", which may be another alias.
-// func (a *Alias) Rhs() Type { return a.fromRHS }
+// Rhs returns the type R on the right-hand side of an alias
+// declaration "type A = R", which may be another alias.
+func (a *Alias) Rhs() Type { return a.fromRHS }
 
 // Unalias returns t if it is not an alias type;
 // otherwise it follows t's alias chain until it
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index 564bbc2..6f8dddb 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -3014,3 +3014,21 @@
 		t.Errorf("Unalias(type B = T[A]) = %q, want %q", got, want)
 	}
 }
+
+func TestAlias_Rhs(t *testing.T) {
+	t.Setenv("GODEBUG", "gotypesalias=1")
+	const src = `package p
+
+type A = B
+type B = C
+type C = int
+`
+
+	pkg := mustTypecheck(src, nil, nil)
+	A := pkg.Scope().Lookup("A")
+
+	got, want := A.Type().(*Alias).Rhs().String(), "p.B"
+	if got != want {
+		t.Errorf("A.Rhs = %s, want %s", got, want)
+	}
+}