diff options
-rw-r--r-- | src/cmd/compile/internal/reflectdata/reflect.go | 9 | ||||
-rw-r--r-- | src/cmd/compile/internal/typecheck/stmt.go | 25 | ||||
-rw-r--r-- | src/cmd/compile/internal/walk/order.go | 24 |
3 files changed, 23 insertions, 35 deletions
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index 316c7eb293..351aaab399 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -1388,7 +1388,7 @@ func WriteBasicTypes() { type typeAndStr struct { t *types.Type - short string + short string // "short" here means NameString regular string } @@ -1401,8 +1401,13 @@ func (a typesByString) Less(i, j int) bool { } // When the only difference between the types is whether // they refer to byte or uint8, such as **byte vs **uint8, - // the types' ShortStrings can be identical. + // the types' NameStrings can be identical. // To preserve deterministic sort ordering, sort these by String(). + // + // TODO(mdempsky): This all seems suspect. Using LinkString would + // avoid naming collisions, and there shouldn't be a reason to care + // about "byte" vs "uint8": they share the same runtime type + // descriptor anyway. if a[i].regular != a[j].regular { return a[i].regular < a[j].regular } diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go index 313491ba0b..54cf508acc 100644 --- a/src/cmd/compile/internal/typecheck/stmt.go +++ b/src/cmd/compile/internal/typecheck/stmt.go @@ -662,29 +662,18 @@ func tcSwitchType(n *ir.SwitchStmt) { } type typeSet struct { - m map[string][]typeSetEntry -} - -type typeSetEntry struct { - pos src.XPos - typ *types.Type + m map[string]src.XPos } func (s *typeSet) add(pos src.XPos, typ *types.Type) { if s.m == nil { - s.m = make(map[string][]typeSetEntry) + s.m = make(map[string]src.XPos) } - // LongString does not uniquely identify types, so we need to - // disambiguate collisions with types.Identical. - // TODO(mdempsky): Add a method that *is* unique. - ls := typ.NameString() - prevs := s.m[ls] - for _, prev := range prevs { - if types.Identical(typ, prev.typ) { - base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev.pos)) - return - } + ls := typ.LinkString() + if prev, ok := s.m[ls]; ok { + base.ErrorfAt(pos, "duplicate case %v in type switch\n\tprevious case at %s", typ, base.FmtPos(prev)) + return } - s.m[ls] = append(prevs, typeSetEntry{pos, typ}) + s.m[ls] = pos } diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go index 59701613c3..9912feba63 100644 --- a/src/cmd/compile/internal/walk/order.go +++ b/src/cmd/compile/internal/walk/order.go @@ -51,7 +51,7 @@ import ( type orderState struct { out []ir.Node // list of generated statements temp []*ir.Name // stack of temporary variables - free map[string][]*ir.Name // free list of unused temporaries, by type.LongString(). + free map[string][]*ir.Name // free list of unused temporaries, by type.LinkString(). edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS } @@ -76,20 +76,14 @@ func (o *orderState) append(stmt ir.Node) { // If clear is true, newTemp emits code to zero the temporary. func (o *orderState) newTemp(t *types.Type, clear bool) *ir.Name { var v *ir.Name - // Note: LongString is close to the type equality we want, - // but not exactly. We still need to double-check with types.Identical. - key := t.NameString() - a := o.free[key] - for i, n := range a { - if types.Identical(t, n.Type()) { - v = a[i] - a[i] = a[len(a)-1] - a = a[:len(a)-1] - o.free[key] = a - break + key := t.LinkString() + if a := o.free[key]; len(a) > 0 { + v = a[len(a)-1] + if !types.Identical(t, v.Type()) { + base.Fatalf("expected %L to have type %v", v, t) } - } - if v == nil { + o.free[key] = a[:len(a)-1] + } else { v = typecheck.Temp(t) } if clear { @@ -370,7 +364,7 @@ func (o *orderState) markTemp() ordermarker { // which must have been returned by markTemp. func (o *orderState) popTemp(mark ordermarker) { for _, n := range o.temp[mark:] { - key := n.Type().NameString() + key := n.Type().LinkString() o.free[key] = append(o.free[key], n) } o.temp = o.temp[:mark] |