Skip to content

Commit 3606e1e

Browse files
committed
Implement support for == operator on type params.
1 parent 370d8c9 commit 3606e1e

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

compiler/expressions.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,23 @@ func (fc *funcContext) translateExpr(expr ast.Expr) *expression {
316316

317317
t := fc.pkgCtx.TypeOf(e.X)
318318
t2 := fc.pkgCtx.TypeOf(e.Y)
319-
_, isInterface := t2.Underlying().(*types.Interface)
320-
if isInterface || types.Identical(t, types.Typ[types.UntypedNil]) {
319+
320+
// Exact type param instantiations are not known at compile time, so
321+
// some operators require special handling.
322+
if (typesutil.IsTypeParam(t) || typesutil.IsTypeParam(t2)) &&
323+
!(typesutil.IsInterface(t) || typesutil.IsInterface(t2)) { // == operator between an interface and other types is handled below.
324+
if !types.Identical(t, t2) {
325+
// This should never happen.
326+
panic(bailout(fmt.Errorf("%s: binary operator %v is applied to different type param types %s and %s", fc.pkgCtx.fileSet.Position(e.Pos()), e.Op, t, t2)))
327+
}
328+
329+
switch e.Op {
330+
case token.EQL:
331+
return fc.formatExpr("$equal(%e, %e, %s)", e.X, e.Y, fc.typeName(t))
332+
}
333+
}
334+
335+
if typesutil.IsInterface(t2) || types.Identical(t, types.Typ[types.UntypedNil]) {
321336
t = t2
322337
}
323338

compiler/typesutil/typesutil.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ func IsGeneric(t types.Type) bool {
130130
}
131131
}
132132

133+
// IsTypeParam returns true if the type is a type param.
134+
func IsTypeParam(t types.Type) bool {
135+
_, ok := t.(*types.TypeParam)
136+
return ok
137+
}
138+
139+
// IsInterface returns true if the type is an interface.
140+
func IsInterface(t types.Type) bool {
141+
_, ok := t.Underlying().(*types.Interface)
142+
return ok && !IsTypeParam(t)
143+
}
144+
133145
// IsMethod returns true if the passed object is a method.
134146
func IsMethod(o types.Object) bool {
135147
f, ok := o.(*types.Func)

tests/gorepo/run.go

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ var knownFails = map[string]failReason{
150150
"fixedbugs/issue48536.go": {category: usesUnsupportedPackage, desc: "https://github.com/gopherjs/gopherjs/issues/1130"},
151151
"fixedbugs/issue53600.go": {category: lowLevelRuntimeDifference, desc: "GopherJS println format is different from Go's"},
152152
"typeparam/issue51733.go": {category: usesUnsupportedPackage, desc: "unsafe: uintptr to struct pointer conversion is unsupported"},
153+
"typeparam/chans.go": {category: neverTerminates, desc: "uses runtime.SetFinalizer() and runtime.GC()."},
153154

154155
// Failures related to the lack of generics support. Ideally, this section
155156
// should be emptied once https://github.com/gopherjs/gopherjs/issues/1013 is
@@ -158,32 +159,19 @@ var knownFails = map[string]failReason{
158159
"typeparam/absdiff2.go": {category: generics, desc: "missing operator support for generic types"},
159160
"typeparam/absdiff3.go": {category: generics, desc: "missing operator support for generic types"},
160161
"typeparam/boundmethod.go": {category: generics, desc: "missing support for method expressions with a type param"},
161-
"typeparam/chans.go": {category: generics, desc: "missing support for the comparable type constraint"},
162162
"typeparam/dictionaryCapture.go": {category: generics, desc: "missing support for basic literals with type params"},
163163
"typeparam/double.go": {category: generics, desc: "make() doesn't support generic slice types"},
164-
"typeparam/equal.go": {category: generics, desc: "missing support for the comparable type constraint"},
165-
"typeparam/fact.go": {category: generics, desc: "missing support for the comparable type constraint"},
166-
"typeparam/graph.go": {category: generics, desc: "missing operator support for generic types"},
167-
"typeparam/index.go": {category: generics, desc: "missing support for the comparable type constraint"},
164+
"typeparam/fact.go": {category: generics, desc: "missing support for basic literals with type params"},
168165
"typeparam/index2.go": {category: generics, desc: "missing index operator support for generic types"},
169166
"typeparam/issue47258.go": {category: generics, desc: "missing operator support for generic types"},
170167
"typeparam/issue47716.go": {category: generics, desc: "unsafe.Sizeof() doesn't work with generic types"},
171-
"typeparam/issue48276a.go": {category: generics, desc: "missing support for the comparable type constraint"},
172168
"typeparam/issue48453.go": {category: generics, desc: "make() doesn't support generic slice types"},
173169
"typeparam/issue49295.go": {category: generics, desc: "len() doesn't support generic pointer to array types"},
174170
"typeparam/issue50193.go": {category: generics, desc: "invalid print format for complex numbers"},
175171
"typeparam/issue51303.go": {category: generics, desc: "missing support for range over type parameter"},
176-
"typeparam/issue51522a.go": {category: generics, desc: "missing support for the comparable type constraint"},
177-
"typeparam/issue51522b.go": {category: generics, desc: "missing support for the comparable type constraint"},
178172
"typeparam/list.go": {category: generics, desc: "missing operator support for generic types"},
179-
"typeparam/maps.go": {category: generics, desc: "missing support for the comparable type constraint"},
180-
"typeparam/metrics.go": {category: generics, desc: "missing support for the comparable type constraint"},
181173
"typeparam/nested.go": {category: generics, desc: "missing comparison operator support for generic types"},
182-
"typeparam/ordered.go": {category: generics, desc: "missing support for the comparable type constraint"},
183-
"typeparam/orderedmap.go": {category: generics, desc: "missing support for the comparable type constraint"},
184-
"typeparam/sets.go": {category: generics, desc: "missing support for the comparable type constraint"},
185174
"typeparam/slices.go": {category: generics, desc: "missing operator support for generic types"},
186-
"typeparam/subdict.go": {category: generics, desc: "missing support for the comparable type constraint"},
187175
"typeparam/typeswitch2.go": {category: generics, desc: "complex types have different print() format"},
188176
"typeparam/typeswitch3.go": {category: generics, desc: "missing support for type switching on generic types"},
189177
"typeparam/typeswitch5.go": {category: generics, desc: "different print() format for floating point types"},

0 commit comments

Comments
 (0)