diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 409225138ea9..97f14e2fe5a4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -33,7 +33,10 @@ object Inferencing { */ def isFullyDefined(tp: Type, force: ForceDegree.Value)(using Context): Boolean = { val nestedCtx = ctx.fresh.setNewTyperState() - val result = new IsFullyDefinedAccumulator(force)(using nestedCtx).process(tp) + val result = + try new IsFullyDefinedAccumulator(force)(using nestedCtx).process(tp) + catch case ex: StackOverflowError => + false // can happen for programs with illegal recusions, e.g. neg/recursive-lower-constraint.scala if (result) nestedCtx.typerState.commit() result } @@ -43,7 +46,7 @@ object Inferencing { */ def canDefineFurther(tp: Type)(using Context): Boolean = val prevConstraint = ctx.typerState.constraint - isFullyDefined(tp, force = ForceDegree.all) + isFullyDefined(tp, force = ForceDegree.failBottom) && (ctx.typerState.constraint ne prevConstraint) /** The fully defined type, where all type variables are forced. @@ -687,7 +690,7 @@ trait Inferencing { this: Typer => val arg = findArg(call) if !arg.isEmpty then - var argType = arg.tpe + var argType = arg.tpe.widenExpr.widenTermRefExpr if !argType.isSingleton then argType = SkolemType(argType) argType <:< tvar case _ => diff --git a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index a744ca39f41f..0a9943067127 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -134,4 +134,5 @@ class ReTyper extends Typer with ReChecking { override protected def addAccessorDefs(cls: Symbol, body: List[Tree])(using Context): List[Tree] = body override protected def checkEqualityEvidence(tree: tpd.Tree, pt: Type)(using Context): Unit = () override protected def matchingApply(methType: MethodOrPoly, pt: FunProto)(using Context): Boolean = true + override protected def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree = promote(call) } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index cda1daafd252..c46a4f7e4c21 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3678,7 +3678,7 @@ class Typer extends Namer return readapt(tree.cast(target)) def recover(failure: SearchFailureType) = - if canDefineFurther(wtp) then readapt(tree) + if canDefineFurther(wtp) || canDefineFurther(pt) then readapt(tree) else err.typeMismatch(tree, pt, failure) pt match @@ -3900,7 +3900,7 @@ class Typer extends Namer report.warning(PureExpressionInStatementPosition(original, exprOwner), original.srcPos) /** Types the body Scala 2 macro declaration `def f = macro ` */ - private def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree = + protected def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree = // TODO check that call is to a method with valid signature def typedPrefix(tree: untpd.RefTree)(splice: Context ?=> Tree => Tree)(using Context): Tree = { tryAlternatively { diff --git a/tests/neg-scalajs/jsconstructortag-error-in-typer.check b/tests/neg-scalajs/jsconstructortag-error-in-typer.check index a18ed693383e..22212957403f 100644 --- a/tests/neg-scalajs/jsconstructortag-error-in-typer.check +++ b/tests/neg-scalajs/jsconstructortag-error-in-typer.check @@ -4,7 +4,7 @@ |no implicit argument of type scala.scalajs.js.ConstructorTag[ScalaClass] was found for parameter tag of method constructorTag in package scala.scalajs.js. |I found: | - | scala.scalajs.js.ConstructorTag.materialize[Nothing] + | scala.scalajs.js.ConstructorTag.materialize[T] | |But method materialize in object ConstructorTag does not match type scala.scalajs.js.ConstructorTag[ScalaClass]. -- Error: tests/neg-scalajs/jsconstructortag-error-in-typer.scala:10:39 ------------------------------------------------ @@ -13,7 +13,7 @@ |no implicit argument of type scala.scalajs.js.ConstructorTag[ScalaTrait] was found for parameter tag of method constructorTag in package scala.scalajs.js. |I found: | - | scala.scalajs.js.ConstructorTag.materialize[Nothing] + | scala.scalajs.js.ConstructorTag.materialize[T] | |But method materialize in object ConstructorTag does not match type scala.scalajs.js.ConstructorTag[ScalaTrait]. -- Error: tests/neg-scalajs/jsconstructortag-error-in-typer.scala:11:45 ------------------------------------------------ @@ -22,6 +22,6 @@ |no implicit argument of type scala.scalajs.js.ConstructorTag[ScalaObject.type] was found for parameter tag of method constructorTag in package scala.scalajs.js. |I found: | - | scala.scalajs.js.ConstructorTag.materialize[Nothing] + | scala.scalajs.js.ConstructorTag.materialize[T] | |But method materialize in object ConstructorTag does not match type scala.scalajs.js.ConstructorTag[ScalaObject.type]. diff --git a/tests/neg/i4986a.check b/tests/neg/i4986a.check index 5375d0fd002b..3aac0a7b2cf3 100644 --- a/tests/neg/i4986a.check +++ b/tests/neg/i4986a.check @@ -4,6 +4,6 @@ |Cannot construct a collection of type List[String] with elements of type Int based on a collection of type List[Int].. |I found: | - | collection.BuildFrom.buildFromIterableOps[Nothing, Nothing, Nothing] + | collection.BuildFrom.buildFromIterableOps[CC, A0, A] | |But method buildFromIterableOps in trait BuildFromLowPriority2 does not match type collection.BuildFrom[List[Int], Int, List[String]]. diff --git a/tests/neg/i7056.check b/tests/neg/i7056.check deleted file mode 100644 index 1695c1e4b6f0..000000000000 --- a/tests/neg/i7056.check +++ /dev/null @@ -1,7 +0,0 @@ --- [E008] Not Found Error: tests/neg/i7056.scala:19:10 ----------------------------------------------------------------- -19 |val z = x.idnt1 // error - | ^^^^^^^ - | value idnt1 is not a member of B. - | An extension method was tried, but could not be fully constructed: - | - | given_T1_T[T](given_PartialId_B).idnt1() diff --git a/tests/pos/i864.scala b/tests/neg/i864.scala similarity index 74% rename from tests/pos/i864.scala rename to tests/neg/i864.scala index 8d2b859998e9..b372d00a569b 100644 --- a/tests/pos/i864.scala +++ b/tests/neg/i864.scala @@ -6,5 +6,5 @@ object C { trait X[T] implicit def u[A, B]: X[A | B] = new X[A | B] {} def y[T](implicit x: X[T]): T = ??? - val x: a.type & b.type | b.type & c.type = y + val x: a.type & b.type | b.type & c.type = y // error } diff --git a/tests/pos/typeclass-encoding2.scala b/tests/neg/typeclass-encoding3.scala similarity index 98% rename from tests/pos/typeclass-encoding2.scala rename to tests/neg/typeclass-encoding3.scala index 13db93f91204..ff403314cd1a 100644 --- a/tests/pos/typeclass-encoding2.scala +++ b/tests/neg/typeclass-encoding3.scala @@ -344,5 +344,6 @@ object functors { ??? // $this.flatMap[A](identity) disabled since it does not typecheck } - MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5))) + MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5))) // ok, synthesizes (using ListMonad) + MonadFlatten.flattened(List(List(1, 2, 3), List(4, 5)))(using ListMonad) // error } \ No newline at end of file diff --git a/tests/pos/depfun.scala b/tests/pos/depfun.scala new file mode 100644 index 000000000000..683b04b32e39 --- /dev/null +++ b/tests/pos/depfun.scala @@ -0,0 +1,17 @@ +// The following test is derived from scala/reflect/TypeTest.scala, but using +// a dependent function instead of a dependent SAM. It shows that the special treatment +// using a DependentTypeTree is not needed for plain function types. +// But for SAM types, the treatment is needed, otherwise TypeTest.scala does +// not typecheck. Todo: Figure out the reason for this difference. +object Test: + + type F[S, T] = (x: S) => Option[x.type & T] + + /** Trivial type test that always succeeds */ + def identity[T]: F[T, T] = Some(_) + + val x: 1 = 1 + val y = identity(x) + val z: Option[1] = y + + diff --git a/tests/neg/i7056.scala b/tests/pos/i7056.scala similarity index 84% rename from tests/neg/i7056.scala rename to tests/pos/i7056.scala index d16aa949000e..a347dfe7b519 100644 --- a/tests/neg/i7056.scala +++ b/tests/pos/i7056.scala @@ -16,4 +16,5 @@ given [T <: A](using PartialId[T]): T1[T] = new T1[T] { given PartialId[B] = ??? val x: B = ??? -val z = x.idnt1 // error +val z = x.idnt1 // used to be an error, now ok +