diff --git a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala index bcfc9288d862..a5e0b62094ef 100644 --- a/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala +++ b/compiler/src/dotty/tools/dotc/typer/VarianceChecker.scala @@ -130,8 +130,6 @@ class VarianceChecker(using Context) { case TypeAlias(alias) => this(status, alias) case _ => foldOver(status, tp) } - case tp: MethodOrPoly => - this(status, tp.resultType) // params will be checked in their TypeDef or ValDef nodes. case AnnotatedType(_, annot) if annot.symbol == defn.UncheckedVarianceAnnot => status case tp: ClassInfo => @@ -144,10 +142,16 @@ class VarianceChecker(using Context) { } } + def checkInfo(info: Type): Option[VarianceError] = info match + case info: MethodOrPoly => + checkInfo(info.resultType) // params will be checked in their TypeDef or ValDef nodes. + case _ => + apply(None, info) + def validateDefinition(base: Symbol): Option[VarianceError] = { val saved = this.base this.base = base - try apply(None, base.info) + try checkInfo(base.info) finally this.base = saved } } diff --git a/tests/neg/i18035.scala b/tests/neg/i18035.scala new file mode 100644 index 000000000000..ba2373481c85 --- /dev/null +++ b/tests/neg/i18035.scala @@ -0,0 +1,15 @@ +import reflect.Selectable.reflectiveSelectable + +class A[+Cov](f: Cov => Unit) { + def foo: { def apply(c: Cov): Unit } = // error + f +} + +val aForString = new A[String](_.length) +// => val aForString: A[String] + +val aForStringIsAForAny: A[Any] = aForString +// => val aForStringIsAForAny: A[Any] + +val _ = aForStringIsAForAny.foo(123) +// => java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')