diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index b101ada545cb..576e69e790cc 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1083,6 +1083,18 @@ object Types { /** Like `dealiasKeepAnnots`, but keeps only refining annotations */ final def dealiasKeepRefiningAnnots(implicit ctx: Context): Type = dealias1(keepIfRefining) + /** If this is a synthetic opaque type seen from inside the opaque companion object, + * its opaque alias, otherwise the type itself. + */ + final def followSyntheticOpaque(implicit ctx: Context): Type = this match { + case tp: TypeProxy if tp.typeSymbol.is(SyntheticOpaque) => + tp.superType match { + case AndType(alias, _) => alias // in this case we are inside the companion object + case _ => this + } + case _ => this + } + /** The result of normalization using `tryNormalize`, or the type itself if * tryNormlize yields NoType */ diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index cea957340d90..8176a28fc309 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -728,13 +728,12 @@ class Typer extends Namer case _: WildcardType => untpd.TypeTree() case _ => untpd.TypeTree(tp) } - pt.stripTypeVar match { - case _ if defn.isNonDepFunctionType(pt) => + pt.stripTypeVar.dealias.followSyntheticOpaque match { + case pt1 if defn.isNonDepFunctionType(pt1) => // if expected parameter type(s) are wildcards, approximate from below. // if expected result type is a wildcard, approximate from above. // this can type the greatest set of admissible closures. - val funType = pt.dealias - (funType.argTypesLo.init, typeTree(funType.argTypesHi.last)) + (pt1.argTypesLo.init, typeTree(pt1.argTypesHi.last)) case SAMType(sam @ MethodTpe(_, formals, restpe)) => (formals, if (sam.isResultDependent) diff --git a/tests/neg/i5481.scala b/tests/neg/i5481.scala new file mode 100644 index 000000000000..274575689384 --- /dev/null +++ b/tests/neg/i5481.scala @@ -0,0 +1,20 @@ +object TypeAlias { + + type Set[A] = A => Boolean + + object Set { + def singleton[A](a: A): Set[A] = _ == a + } +} + +object OpaqueType { + + opaque type Set[A] = A => Boolean + + object Set { + def singleton[A](a: A): Set[A] = _ == a + def singleton0[A](a: A): Set[A] = (_: A) == a + } + + def singleton[A](a: A): Set[A] = _ == a // error: missing parameter type +} \ No newline at end of file diff --git a/tests/pos/i5481.scala b/tests/pos/i5481.scala new file mode 100644 index 000000000000..102121b9ede5 --- /dev/null +++ b/tests/pos/i5481.scala @@ -0,0 +1,19 @@ +object TypeAlias { + + type Set[A] = A => Boolean + + object Set { + def singleton[A](a: A): Set[A] = _ == a + } +} + +object OpaqueType { + + opaque type Set[A] = A => Boolean + + object Set { + def singleton[A](a: A): Set[A] = _ == a + def singleton0[A](a: A): Set[A] = (_: A) == a + } + +} \ No newline at end of file