import (
"cmd/compile/internal/types"
"cmd/internal/objabi"
- "cmd/internal/src"
"fmt"
"math"
"strings"
}
n.Op = OTYPE
n.Type = types.NewMap(l.Type, r.Type)
-
- // map key validation
- alg, bad := algtype1(l.Type)
- if alg == ANOEQ {
- if bad.Etype == TFORW {
- // queue check for map until all the types are done settling.
- mapqueue = append(mapqueue, mapqueueval{l, n.Pos})
- } else if bad.Etype != TANY {
- // no need to queue, key is already bad
- yyerror("invalid map key type %v", l.Type)
- }
- }
+ mapqueue = append(mapqueue, n) // check map keys when all types are settled
n.Left = nil
n.Right = nil
return nn
}
-var ntypecheckdeftype int
+var mapqueue []*Node
-type mapqueueval struct {
- n *Node
- lno src.XPos
+func checkMapKeys() {
+ for _, n := range mapqueue {
+ k := n.Type.MapType().Key
+ if !k.Broke() && !IsComparable(k) {
+ yyerrorl(n.Pos, "invalid map key type %v", k)
+ }
+ }
+ mapqueue = nil
}
-// tracks the line numbers at which forward types are first used as map keys
-var mapqueue []mapqueueval
-
func copytype(n *Node, t *types.Type) {
if t.Etype == TFORW {
// This type isn't computed yet; when it is, update n.
}
func typecheckdeftype(n *Node) {
- ntypecheckdeftype++
lno := lineno
setlineno(n)
n.Type.Sym = n.Sym
}
lineno = lno
-
- // if there are no type definitions going on, it's safe to
- // try to validate the map key types for the interfaces
- // we just read.
- if ntypecheckdeftype == 1 {
- for _, e := range mapqueue {
- lineno = e.lno
- if !IsComparable(e.n.Type) {
- yyerror("invalid map key type %v", e.n.Type)
- }
- }
- mapqueue = nil
- lineno = lno
- }
-
- ntypecheckdeftype--
}
func typecheckdef(n *Node) {
--- /dev/null
+// errorcheck
+
+// 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 main
+
+type T0 T0 // ERROR "invalid recursive type"
+type _ map[T0]int
+
+type T1 struct{ T1 } // ERROR "invalid recursive type"
+type _ map[T1]int
+
+func f() {
+ type T2 T2 // ERROR "invalid recursive type"
+ type _ map[T2]int
+}
+
+func g() {
+ type T3 struct{ T3 } // ERROR "invalid recursive type"
+ type _ map[T3]int
+}
+
+func h() {
+ type T4 struct{ m map[T4]int } // ERROR "invalid map key"
+ type _ map[T4]int // ERROR "invalid map key"
+}