From 2a414136dab1c5dc9f385804572675d93ba6d411 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 27 Apr 2021 16:00:35 +0200 Subject: [PATCH] Fix signatures involving WildcardTypes A `WildcardType` never appears in the type of a tree, but it can appear in an expected type and because TypeComparer checks if `tp1.signature consistentParams tp2.signature`, we can end up calling `sigName` on a `WildcardType`. Before this commit, the result was either a custom type name or the upper-bound of the wildcard, but both of these options means that `consistentParams` could return false in situations where the two method types would in fact match. We fix this by always returning `tpnme.Uninstantiated`, meaning that `consistentParams` will always allow a wildcard to match any other type. This does not cause any over-approximation because the TypeComparer will always check that the actual types match after checking that the signatures match. Also use tpnme.ERROR instead of tpnme.Wildcard for ErrorType and NoType to make it easier to spot their usage. Fixes #11481. --- compiler/src/dotty/tools/dotc/core/TypeErasure.scala | 6 +++--- tests/pos/i11481.scala | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i11481.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 5ce82de63eed..9b82aa7cba25 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -821,10 +821,10 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst sigName(this(tp)) case tp: TypeProxy => sigName(tp.underlying) - case _: ErrorType | WildcardType | NoType => - tpnme.WILDCARD case tp: WildcardType => - sigName(tp.optBounds) + tpnme.Uninstantiated + case _: ErrorType | NoType => + tpnme.ERROR case _ => val erasedTp = this(tp) assert(erasedTp ne tp, tp) diff --git a/tests/pos/i11481.scala b/tests/pos/i11481.scala new file mode 100644 index 000000000000..99fa6a250ff0 --- /dev/null +++ b/tests/pos/i11481.scala @@ -0,0 +1,2 @@ +case class Foo[F[_]](f: {def f(x: F[Int]): Object}) +case class Bar[F[_], G[_]](f: [B] => F[B] => G[B])