diff --git a/compiler/src/dotty/tools/dotc/core/TyperState.scala b/compiler/src/dotty/tools/dotc/core/TyperState.scala index 160d7749de61..d4345916ba77 100644 --- a/compiler/src/dotty/tools/dotc/core/TyperState.scala +++ b/compiler/src/dotty/tools/dotc/core/TyperState.scala @@ -139,14 +139,15 @@ class TyperState() { def uncommittedAncestor: TyperState = if (isCommitted && previous != null) previous.uncheckedNN.uncommittedAncestor else this - /** Commit typer state so that its information is copied into current typer state + /** Commit `this` typer state by copying information into the current typer state, + * where "current" means contextual, so meaning `ctx.typerState`. * In addition (1) the owning state of undetermined or temporarily instantiated * type variables changes from this typer state to the current one. (2) Variables * that were temporarily instantiated in the current typer state are permanently * instantiated instead. * * A note on merging: An interesting test case is isApplicableSafe.scala. It turns out that this - * requires a context merge using the new `&' operator. Sequence of actions: + * requires a context merge using the new `&` operator. Sequence of actions: * 1) Typecheck argument in typerstate 1. * 2) Cache argument. * 3) Evolve same typer state (to typecheck other arguments, say) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8a9d44cb8d25..dda09d3d0e99 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4879,7 +4879,7 @@ object Types extends TypeUtils { def origin: TypeParamRef = currentOrigin /** Set origin to new parameter. Called if we merge two conflicting constraints. - * See OrderingConstraint#merge, OrderingConstraint#rename + * See OrderingConstraint#merge */ def setOrigin(p: TypeParamRef) = currentOrigin = p diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index a69a63d1ceef..370627d23e59 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -71,7 +71,8 @@ object ProtoTypes { |constraint was: ${ctx.typerState.constraint} |constraint now: ${newctx.typerState.constraint}""") if result && (ctx.typerState.constraint ne newctx.typerState.constraint) then - newctx.typerState.commit() + newctx.typerState.gc() // Remove any type lambdas and tvars added via testCompat + newctx.typerState.commit() // Commit the rest of the typer state information result case _ => testCompat else explore(testCompat) diff --git a/tests/pos/interleaving-overload.cleanup.scala b/tests/pos/interleaving-overload.cleanup.scala new file mode 100644 index 000000000000..e7f7c2cfe3bd --- /dev/null +++ b/tests/pos/interleaving-overload.cleanup.scala @@ -0,0 +1,10 @@ +// Justifies the need to add defn.PolyFunctionOf in simplify +// Without, the TypeVar for the U in fn's lambda +// replaces the TypeParamRef U, in simplify. +class B[U] +class Test(): + def fn[T]: [U] => Int => B[U] = [U] => (x: Int) => new B[U]() + def test(): Unit = + fn(1) + fn(2) + () diff --git a/tests/pos/zipped.min.scala b/tests/pos/zipped.min.scala new file mode 100644 index 000000000000..5d15b3fae240 --- /dev/null +++ b/tests/pos/zipped.min.scala @@ -0,0 +1,15 @@ +// Justifies the need for TypeApply in tryInsertImplicitOnQualifier +// after failing ys.map[?B, C] using Zipped2's map +// we want to try ys.map[?B] using Coll's map, after toColl +final class Coll[+A]: + def map[B](f: A => B): Coll[B] = new Coll[B] + def lazyZip[B](that: Coll[B]): Zipped2[A, B] = new Zipped2[A, B](this, that) +final class Zipped2[+X, +Y](xs: Coll[X], ys: Coll[Y]): + def map[B, C](f: (X, Y) => B): Coll[C] = new Coll[C] +object Zipped2: + import scala.language.implicitConversions + implicit def toColl[X, Y](zipped2: Zipped2[X, Y]): Coll[(X, Y)] = new Coll[(X, Y)] +class Test: + def test(xs: Coll[Int]): Unit = + val ys = xs.lazyZip(xs) + ys.map((x: (Int, Int)) => x._1 + x._2)