From: Robert Griesemer Date: Tue, 16 Nov 2021 19:36:09 +0000 (-0800) Subject: cmd/compile/internal/types2: add a test for Context deduplication of hash collisions X-Git-Tag: go1.18beta1~276 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2f937d9bfcbb1e95c089a3af37677bacb185aedb;p=gostls13.git cmd/compile/internal/types2: add a test for Context deduplication of hash collisions This CL is a clean port of CL 363517 from go/types to types2, with the exception that types_test.go was not removed because it's still needed to set a types2-specific test flag. Change-Id: I12177866537c0f95f3fa36fa0f4aa02016609ca9 Reviewed-on: https://go-review.googlesource.com/c/go/+/364494 Trust: Robert Griesemer Reviewed-by: Robert Findley --- diff --git a/src/cmd/compile/internal/types2/context_test.go b/src/cmd/compile/internal/types2/context_test.go new file mode 100644 index 0000000000..aa649b1448 --- /dev/null +++ b/src/cmd/compile/internal/types2/context_test.go @@ -0,0 +1,69 @@ +// Copyright 2021 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 types2 + +import ( + "testing" +) + +func TestContextHashCollisions(t *testing.T) { + if debug { + t.Skip("hash collisions are expected, and would fail debug assertions") + } + // Unit test the de-duplication fall-back logic in Context. + // + // We can't test this via Instantiate because this is only a fall-back in + // case our hash is imperfect. + // + // These lookups and updates use reasonable looking types in an attempt to + // make them robust to internal type assertions, but could equally well use + // arbitrary types. + + // Create some distinct origin types. nullaryP and nullaryQ have no + // parameters and are identical (but have different type parameter names). + // unaryP has a parameter. + var nullaryP, nullaryQ, unaryP Type + { + // type nullaryP = func[P any]() + tparam := NewTypeParam(NewTypeName(nopos, nil, "P", nil), &emptyInterface) + nullaryP = NewSignatureType(nil, nil, []*TypeParam{tparam}, nil, nil, false) + } + { + // type nullaryQ = func[Q any]() + tparam := NewTypeParam(NewTypeName(nopos, nil, "Q", nil), &emptyInterface) + nullaryQ = NewSignatureType(nil, nil, []*TypeParam{tparam}, nil, nil, false) + } + { + // type unaryP = func[P any](_ P) + tparam := NewTypeParam(NewTypeName(nopos, nil, "P", nil), &emptyInterface) + params := NewTuple(NewVar(nopos, nil, "_", tparam)) + unaryP = NewSignatureType(nil, nil, []*TypeParam{tparam}, params, nil, false) + } + + ctxt := NewContext() + + // Update the context with an instantiation of nullaryP. + inst := NewSignatureType(nil, nil, nil, nil, nil, false) + if got := ctxt.update("", nullaryP, []Type{Typ[Int]}, inst); got != inst { + t.Error("bad") + } + + // unaryP is not identical to nullaryP, so we should not get inst when + // instantiated with identical type arguments. + if got := ctxt.lookup("", unaryP, []Type{Typ[Int]}); got != nil { + t.Error("bad") + } + + // nullaryQ is identical to nullaryP, so we *should* get inst when + // instantiated with identical type arguments. + if got := ctxt.lookup("", nullaryQ, []Type{Typ[Int]}); got != inst { + t.Error("bad") + } + + // ...but verify we don't get inst with different type arguments. + if got := ctxt.lookup("", nullaryQ, []Type{Typ[String]}); got != nil { + t.Error("bad") + } +} diff --git a/src/cmd/compile/internal/types2/types_test.go b/src/cmd/compile/internal/types2/types_test.go index 1525844f2d..11dca0b53d 100644 --- a/src/cmd/compile/internal/types2/types_test.go +++ b/src/cmd/compile/internal/types2/types_test.go @@ -7,6 +7,3 @@ package types2 func init() { acceptMethodTypeParams = true } - -// Debug is set if types2 is built with debug mode enabled. -const Debug = debug