From 4b6ca212715b7aa66930bc9c3f1e46b096f5f383 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Oudompheng?= <oudomphe@phare.normalesup.org>
Date: Wed, 3 Apr 2013 08:18:30 +0200
Subject: [PATCH] cmd/gc: be more tolerant with recursive types when checking
 map types.

A nested TFORW type would push algtype1 into an impossible case.

Fixes #5125.

R=golang-dev, daniel.morsing
CC=golang-dev
https://golang.org/cl/8213043
---
 src/cmd/gc/subr.c                    | 13 +++++++++++--
 test/fixedbugs/issue5125.dir/bug.go  | 17 +++++++++++++++++
 test/fixedbugs/issue5125.dir/main.go | 10 ++++++++++
 test/fixedbugs/issue5125.go          | 10 ++++++++++
 4 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 test/fixedbugs/issue5125.dir/bug.go
 create mode 100644 test/fixedbugs/issue5125.dir/main.go
 create mode 100644 test/fixedbugs/issue5125.go

diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 255f4c73ad..bd78fb0246 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -548,6 +548,12 @@ algtype1(Type *t, Type **bad)
 		*bad = T;
 
 	switch(t->etype) {
+	case TANY:
+	case TFORW:
+		// will be defined later.
+		*bad = t;
+		return -1;
+
 	case TINT8:
 	case TUINT8:
 	case TINT16:
@@ -665,11 +671,14 @@ Type*
 maptype(Type *key, Type *val)
 {
 	Type *t;
+	Type *bad;
+	int atype;
 
 	if(key != nil) {
-		switch(key->etype) {
+		atype = algtype1(key, &bad);
+		switch(bad == T ? key->etype : bad->etype) {
 		default:
-			if(algtype1(key, nil) == ANOEQ)
+			if(atype == ANOEQ)
 				yyerror("invalid map key type %T", key);
 			break;
 		case TANY:
diff --git a/test/fixedbugs/issue5125.dir/bug.go b/test/fixedbugs/issue5125.dir/bug.go
new file mode 100644
index 0000000000..2fdf0f9bb8
--- /dev/null
+++ b/test/fixedbugs/issue5125.dir/bug.go
@@ -0,0 +1,17 @@
+// Copyright 2013 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 bug
+
+type Node interface {
+	Eval(s *Scene)
+}
+
+type plug struct {
+	node Node
+}
+
+type Scene struct {
+	changed map[plug]bool
+}
diff --git a/test/fixedbugs/issue5125.dir/main.go b/test/fixedbugs/issue5125.dir/main.go
new file mode 100644
index 0000000000..47acdeba8a
--- /dev/null
+++ b/test/fixedbugs/issue5125.dir/main.go
@@ -0,0 +1,10 @@
+// Copyright 2013 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 main
+
+import _ "./bug"
+
+func main() {
+}
diff --git a/test/fixedbugs/issue5125.go b/test/fixedbugs/issue5125.go
new file mode 100644
index 0000000000..c049df3e2f
--- /dev/null
+++ b/test/fixedbugs/issue5125.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2013 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.
+
+// Issue 5125: cyclic dependencies between types confuse
+// the hashability test during import.
+
+package ignored
-- 
2.30.9