From b35f85fc7b677615d875b133f5052c284d7e0ed8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 24 Jul 2023 15:34:17 +0100 Subject: [PATCH] Record failures to adapt application arguments --- .../tools/dotc/core/OrderingConstraint.scala | 4 +- .../dotty/tools/dotc/typer/Applications.scala | 2 +- .../tools/pc/tests/hover/HoverTypeSuite.scala | 4 +- tests/neg-macros/i16522.check | 14 ++++++- tests/neg-macros/i16522.scala | 2 +- tests/neg-macros/i6762.scala | 2 +- tests/neg/enum-values.check | 8 ++-- tests/neg/enumsAccess.scala | 2 +- tests/neg/i6779.check | 2 +- tests/neg/recursive-lower-constraint.scala | 2 +- tests/neg/syntax-error-recovery.check | 6 --- tests/neg/syntax-error-recovery.scala | 2 +- tests/pos/i18163.orig.scala | 40 +++++++++++++++++++ tests/pos/i18163.scala | 21 ++++++++++ 14 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 tests/pos/i18163.orig.scala create mode 100644 tests/pos/i18163.scala diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index faea30390d2b..0328cea9b3ca 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -344,7 +344,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds, if newSet.isEmpty then deps.remove(referenced) else deps.updated(referenced, newSet) - def traverse(t: Type) = t match + def traverse(t: Type) = try + t match case param: TypeParamRef => if hasBounds(param) then if variance >= 0 then coDeps = update(coDeps, param) @@ -356,6 +357,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, seen += tp traverse(tp.ref) case _ => traverseChildren(t) + catch case ex: Throwable => handleRecursive("adjust", t.show, ex) end Adjuster /** Adjust dependencies to account for the delta of previous entry `prevEntry` diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 81d7ad23913b..d1dffdbc9f9c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -844,7 +844,7 @@ trait Applications extends Compatibility { var typedArgs = typedArgBuf.toList def app0 = cpy.Apply(app)(normalizedFun, typedArgs) // needs to be a `def` because typedArgs can change later val app1 = - if (!success) app0.withType(UnspecifiedErrorType) + if (!success || typedArgs.exists(_.tpe.isError)) app0.withType(UnspecifiedErrorType) else { if !sameSeq(args, orderedArgs) && !isJavaAnnotConstr(methRef.symbol) diff --git a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala index f370b9ab50d7..e47eb48068d2 100644 --- a/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala +++ b/presentation-compiler/test/dotty/tools/pc/tests/hover/HoverTypeSuite.scala @@ -134,7 +134,7 @@ class HoverTypeSuite extends BaseHoverSuite: |class C |object Foo: | extension [T](using A)(s: T)(using B) - | def double[G](using C)(times: G) = (s.toString + s.toString) * times + | def double[G <: Int](using C)(times: G) = (s.toString + s.toString) * times | end extension | given A with {} | given B with {} @@ -142,7 +142,7 @@ class HoverTypeSuite extends BaseHoverSuite: | "".<> |end Foo |""".stripMargin, - "extension [T](using A)(s: T) def double(using B)[G](using C)(times: G): String".hover + "extension [T](using A)(s: T) def double(using B)[G <: Int](using C)(times: G): String".hover ) @Test def `extension-methods-complex-binary` = diff --git a/tests/neg-macros/i16522.check b/tests/neg-macros/i16522.check index 17eb38f7052d..75b678ac2f8e 100644 --- a/tests/neg-macros/i16522.check +++ b/tests/neg-macros/i16522.check @@ -1,7 +1,19 @@ -- [E007] Type Mismatch Error: tests/neg-macros/i16522.scala:10:45 ----------------------------------------------------- -10 | case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error +10 | case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error // error // error | ^^^^^^^ | Found: tl | Required: HList | | longer explanation available when compiling with `-explain` +-- [E006] Not Found Error: tests/neg-macros/i16522.scala:10:62 --------------------------------------------------------- +10 | case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error // error // error + | ^^ + | Not found: h1 + | + | longer explanation available when compiling with `-explain` +-- [E006] Not Found Error: tests/neg-macros/i16522.scala:10:78 --------------------------------------------------------- +10 | case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error // error // error + | ^^ + | Not found: h2 + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg-macros/i16522.scala b/tests/neg-macros/i16522.scala index cbb0bb733ab7..4f57f029f85f 100644 --- a/tests/neg-macros/i16522.scala +++ b/tests/neg-macros/i16522.scala @@ -7,7 +7,7 @@ def showFirstTwoImpl(e: Expr[HList])(using Quotes): Expr[String] = { e match { case '{HCons($h1, HCons($h2, $_))} => '{$h1.toString ++ $h2.toString} - case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error + case '{HCons($h1: hd1, HCons($h2: hd2, $_ : tl))} => '{$h1.toString ++ $h2.toString} // error // error // error case '{HCons[hd, HCons[sd, tl]]($h1, HCons($h2, $_))} => '{$h1.toString ++ $h2.toString} case _ => '{""} } diff --git a/tests/neg-macros/i6762.scala b/tests/neg-macros/i6762.scala index a8df289b26c2..054945e213d6 100644 --- a/tests/neg-macros/i6762.scala +++ b/tests/neg-macros/i6762.scala @@ -2,4 +2,4 @@ import scala.quoted.* type G[X] case class Foo[T](x: T) -def f(word: String)(using Quotes): Expr[Foo[G[String]]] = '{Foo(${Expr(word)})} // error // error +def f(word: String)(using Quotes): Expr[Foo[G[String]]] = '{Foo(${Expr(word)})} // error diff --git a/tests/neg/enum-values.check b/tests/neg/enum-values.check index 37990e8f312e..23337de1b2c4 100644 --- a/tests/neg/enum-values.check +++ b/tests/neg/enum-values.check @@ -24,8 +24,8 @@ | | failed with: | - | Found: Array[example.Tag[?]] - | Required: Array[example.ListLike[?]] + | Found: example.ListLike.type + | Required: Nothing -- [E008] Not Found Error: tests/neg/enum-values.scala:34:52 ----------------------------------------------------------- 34 | val typeCtorsK: Array[TypeCtorsK[?]] = TypeCtorsK.values // error | ^^^^^^^^^^^^^^^^^ @@ -38,8 +38,8 @@ | | failed with: | - | Found: Array[example.Tag[?]] - | Required: Array[example.TypeCtorsK[?[_$1]]] + | Found: example.TypeCtorsK.type + | Required: Nothing -- [E008] Not Found Error: tests/neg/enum-values.scala:36:6 ------------------------------------------------------------ 36 | Tag.valueOf("Int") // error | ^^^^^^^^^^^ diff --git a/tests/neg/enumsAccess.scala b/tests/neg/enumsAccess.scala index 18b91b346b6a..8a8e9af8910f 100644 --- a/tests/neg/enumsAccess.scala +++ b/tests/neg/enumsAccess.scala @@ -63,7 +63,7 @@ object test5 { enum E5[T](x: T) { case C3() extends E5[INT](defaultX)// error: illegal reference // error: illegal reference case C4 extends E5[INT](defaultX) // error: illegal reference // error: illegal reference - case C5 extends E5[E5[_]](E5.this) // error: type mismatch + case C5 extends E5[E5[_]](E5.this) // error: cannot be instantiated // error: conflicting base types // error: type mismatch } object E5 { diff --git a/tests/neg/i6779.check b/tests/neg/i6779.check index 8e05c22eb640..f1e1b9d5557b 100644 --- a/tests/neg/i6779.check +++ b/tests/neg/i6779.check @@ -11,7 +11,7 @@ | value f is not a member of T. | An extension method was tried, but could not be fully constructed: | - | Test.f[G[T]](x)(given_Stuff) + | Test.f[G[T]](x) | | failed with: | diff --git a/tests/neg/recursive-lower-constraint.scala b/tests/neg/recursive-lower-constraint.scala index 8009ab5fce6e..cf45d8b95171 100644 --- a/tests/neg/recursive-lower-constraint.scala +++ b/tests/neg/recursive-lower-constraint.scala @@ -3,5 +3,5 @@ class Bar extends Foo[Bar] class A { def foo[T <: Foo[T], U >: Foo[T] <: T](x: T): T = x - foo(new Bar) // error + foo(new Bar) // error // error } diff --git a/tests/neg/syntax-error-recovery.check b/tests/neg/syntax-error-recovery.check index 0bf626210fed..18d877833d79 100644 --- a/tests/neg/syntax-error-recovery.check +++ b/tests/neg/syntax-error-recovery.check @@ -94,12 +94,6 @@ | Not found: bam | | longer explanation available when compiling with `-explain` --- [E006] Not Found Error: tests/neg/syntax-error-recovery.scala:61:10 ------------------------------------------------- -61 | println(bam) // error - | ^^^ - | Not found: bam - | - | longer explanation available when compiling with `-explain` -- [E129] Potential Issue Warning: tests/neg/syntax-error-recovery.scala:7:2 ------------------------------------------- 6 | 2 7 | } diff --git a/tests/neg/syntax-error-recovery.scala b/tests/neg/syntax-error-recovery.scala index 775abeb97bdb..b6663cc9c70a 100644 --- a/tests/neg/syntax-error-recovery.scala +++ b/tests/neg/syntax-error-recovery.scala @@ -58,5 +58,5 @@ object Test2: def foo5(x: Int) = foo2(foo2(,) // error // error - println(bam) // error + println(bam) // error \ No newline at end of file diff --git a/tests/pos/i18163.orig.scala b/tests/pos/i18163.orig.scala new file mode 100644 index 000000000000..eb0627254156 --- /dev/null +++ b/tests/pos/i18163.orig.scala @@ -0,0 +1,40 @@ +import scala.language.implicitConversions + +// We do have 2 `contramap` functions, one provided via `LoggerSyntax` other via `Contravariant.Ops` +// `ContravariantMonoidal` given instances are not used, and they do not match our type. Code fails when we have at least 2 instances of them +// Removal of `import catsSyntax._` allow to compile code +// Removal of `import odinSyntax.LoggerSyntax` and remaining `catsSyntax` would fail to compile the `def fails` + +trait Foo[A] +trait Bar[A] + +trait WriterT[F[_]: Contravariant, L, V]: + def contramap[Z](fn: Z => V): WriterT[F, L, Z] = ??? +trait Logger[F[_]] +class WriterTLogger[F[_]] extends Logger[[G] =>> WriterT[F, List[String], G]] + +trait ContravariantMonoidal[F[_]] extends Invariant[F] with Contravariant[F] +trait Invariant[F[_]] +object Invariant: + given ContravariantMonoidal[Foo] = ??? + given ContravariantMonoidal[Bar] = ??? + +trait Contravariant[F[_]] extends Invariant[F] +object Contravariant: + trait Ops[F[_], A]: + def contramap[B](f: B => A): F[B] = ??? + +object catsSyntax: + implicit def toContravariantOps[F[_]: Contravariant, A](target: F[A]): Contravariant.Ops[F, A] = ??? + +object odinSyntax: + implicit class LoggerSyntax[F[_]](logger: Logger[F]): + def contramap(f: String => String): Logger[F] = ??? + +import catsSyntax._ +import odinSyntax.LoggerSyntax + +class Test: + def fails = new WriterTLogger[Option].contramap(identity) + def works = LoggerSyntax(new WriterTLogger[Option]).contramap(identity) + diff --git a/tests/pos/i18163.scala b/tests/pos/i18163.scala new file mode 100644 index 000000000000..5c364a50dd57 --- /dev/null +++ b/tests/pos/i18163.scala @@ -0,0 +1,21 @@ +import scala.language.implicitConversions + +trait Foo[A] +trait Bar[B] +trait Qux[C] +class Log[K[_]] + +trait Inv[F[_]] +object Inv: + given monFoo: Inv[Foo] = ??? + given monBar: Inv[Bar] = ??? + +trait InvOps[H[_], D] { def desc(s: String): H[D] = ??? } +trait LogOps[L[_]] { def desc(s: String): Log[L] = ??? } + +class Test: + implicit def LogOps[Q[_]](l: Log[Q]): LogOps[Q] = ??? + implicit def InvOps[J[_], E](j11: J[E])(implicit z: Inv[J]): InvOps[J, E] = ??? + + def fails = new Log[Qux].desc("fails") + def works = LogOps[Qux](new Log[Qux]).desc("works")