Skip to content

Commit 7fb2a9d

Browse files
authored
Merge pull request #88 from scala/backport-lts-3.3-21466
Backport "Remove tvars introduced while testing normalizedCompatible" to 3.3 LTS
2 parents 9d23aee + 716dd45 commit 7fb2a9d

File tree

11 files changed

+73
-17
lines changed

11 files changed

+73
-17
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ jobs:
773773
WORKFLOW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
774774
with:
775775
filename: .github/workflows/issue_nightly_failed.md
776-
776+
build-sdk-package:
777777
uses: ./.github/workflows/build-sdk.yml
778778
if:
779779
(github.event_name == 'pull_request' && !contains(github.event.pull_request.body, '[skip ci]')) ||

compiler/src/dotty/tools/dotc/ast/tpd.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11671167
* recursion in the self type.
11681168
*/
11691169
def ensureHasSym(sym: Symbol)(using Context): Unit =
1170-
if sym.exists && sym != tree.symbol then
1170+
if sym.exists && sym != tree.symbol && sym.isTerm then
11711171
typr.println(i"correcting definition symbol from ${tree.symbol.showLocated} to ${sym.showLocated}")
11721172
tree.overwriteType(NamedType(sym.owner.thisType, sym.asTerm.name, sym.denot))
11731173

compiler/src/dotty/tools/dotc/core/TyperState.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,15 @@ class TyperState() {
138138
def uncommittedAncestor: TyperState =
139139
if (isCommitted && previous != null) previous.uncheckedNN.uncommittedAncestor else this
140140

141-
/** Commit typer state so that its information is copied into current typer state
141+
/** Commit `this` typer state by copying information into the current typer state,
142+
* where "current" means contextual, so meaning `ctx.typerState`.
142143
* In addition (1) the owning state of undetermined or temporarily instantiated
143144
* type variables changes from this typer state to the current one. (2) Variables
144145
* that were temporarily instantiated in the current typer state are permanently
145146
* instantiated instead.
146147
*
147148
* A note on merging: An interesting test case is isApplicableSafe.scala. It turns out that this
148-
* requires a context merge using the new `&' operator. Sequence of actions:
149+
* requires a context merge using the new `&` operator. Sequence of actions:
149150
* 1) Typecheck argument in typerstate 1.
150151
* 2) Cache argument.
151152
* 3) Evolve same typer state (to typecheck other arguments, say)

compiler/src/dotty/tools/dotc/core/Types.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -4021,6 +4021,7 @@ object Types extends TypeUtils {
40214021
protected def prefixString: String = companion.prefixString
40224022
}
40234023

4024+
// Actually.. not cached. MethodOrPoly are `UncachedGroundType`s.
40244025
final class CachedMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type, val companion: MethodTypeCompanion)
40254026
extends MethodType(paramNames)(paramInfosExp, resultTypeExp)
40264027

@@ -4800,7 +4801,7 @@ object Types extends TypeUtils {
48004801
def origin: TypeParamRef = currentOrigin
48014802

48024803
/** Set origin to new parameter. Called if we merge two conflicting constraints.
4803-
* See OrderingConstraint#merge, OrderingConstraint#rename
4804+
* See OrderingConstraint#merge
48044805
*/
48054806
def setOrigin(p: TypeParamRef) = currentOrigin = p
48064807

compiler/src/dotty/tools/dotc/printing/Formatting.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ object Formatting {
185185
* The idea is to do this for known cases that are useful and then fall back
186186
* on regular syntax highlighting for the cases which are unhandled.
187187
*
188-
* Please not that if used in combination with `disambiguateTypes` the
188+
* Please note that if used in combination with `disambiguateTypes` the
189189
* correct `Context` for printing should also be passed when calling the
190190
* method.
191191
*

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
224224
val refsText = if refs.isUniversal then rootSetText else toTextCaptureSet(refs)
225225
toTextCapturing(parent, refsText, boxText)
226226
case tp: PreviousErrorType if ctx.settings.XprintTypes.value =>
227-
"<error>" // do not print previously reported error message because they may try to print this error type again recuresevely
227+
"<error>" // do not print previously reported error message because they may try to print this error type again recursively
228228
case tp: ErrorType =>
229229
s"<error ${tp.msg.message}>"
230230
case tp: WildcardType =>

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

+7
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ object ProtoTypes {
6969
|constraint was: ${ctx.typerState.constraint}
7070
|constraint now: ${newctx.typerState.constraint}""")
7171
if result && (ctx.typerState.constraint ne newctx.typerState.constraint) then
72+
// Remove all type lambdas and tvars introduced by testCompat
73+
for tvar <- newctx.typerState.ownedVars do
74+
inContext(newctx):
75+
if !tvar.isInstantiated then
76+
tvar.instantiate(fromBelow = false) // any direction
77+
78+
// commit any remaining changes in typer state
7279
newctx.typerState.commit()
7380
result
7481
case _ => testCompat

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

+9-8
Original file line numberDiff line numberDiff line change
@@ -352,20 +352,21 @@ trait TypeAssigner {
352352
resultType1)
353353
}
354354
}
355+
else if !args.hasSameLengthAs(paramNames) then
356+
wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.srcPos)
355357
else {
356358
// Make sure arguments don't contain the type `pt` itself.
357-
// make a copy of the argument if that's the case.
359+
// Make a copy of `pt` if that's the case.
358360
// This is done to compensate for the fact that normally every
359361
// reference to a polytype would have to be a fresh copy of that type,
360362
// but we want to avoid that because it would increase compilation cost.
361363
// See pos/i6682a.scala for a test case where the defensive copying matters.
362-
val ensureFresh = new TypeMap with CaptureSet.IdempotentCaptRefMap:
363-
def apply(tp: Type) = mapOver(
364-
if tp eq pt then pt.newLikeThis(pt.paramNames, pt.paramInfos, pt.resType)
365-
else tp)
366-
val argTypes = args.tpes.mapConserve(ensureFresh)
367-
if (argTypes.hasSameLengthAs(paramNames)) pt.instantiate(argTypes)
368-
else wrongNumberOfTypeArgs(fn.tpe, pt.typeParams, args, tree.srcPos)
364+
val needsFresh = new ExistsAccumulator(_ eq pt, StopAt.None, forceLazy = false)
365+
val argTypes = args.tpes
366+
val pt1 = if argTypes.exists(needsFresh(false, _)) then
367+
pt.newLikeThis(pt.paramNames, pt.paramInfos, pt.resType)
368+
else pt
369+
pt1.instantiate(argTypes)
369370
}
370371
}
371372
case err: ErrorType =>

compiler/src/dotty/tools/dotc/typer/Typer.scala

+24-2
Original file line numberDiff line numberDiff line change
@@ -2501,7 +2501,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
25012501
case rhs => typedExpr(rhs, tpt1.tpe.widenExpr)
25022502
}
25032503
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
2504-
postProcessInfo(sym)
2504+
postProcessInfo(vdef1, sym)
25052505
vdef1.setDefTree
25062506
}
25072507

@@ -4391,7 +4391,29 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43914391
var typeArgs = tree match
43924392
case Select(qual, nme.CONSTRUCTOR) => qual.tpe.widenDealias.argTypesLo.map(TypeTree(_))
43934393
case _ => Nil
4394-
if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree))
4394+
if typeArgs.isEmpty then
4395+
val poly1 = tree match
4396+
case Select(qual, nme.apply) => qual.tpe.widen match
4397+
case defn.PolyFunctionOf(_) =>
4398+
// Given a poly function, like the one in i6682a:
4399+
// val v = [T] => (y:T) => (x:y.type) => 3
4400+
// It's possible to apply `v(v)` which extends to:
4401+
// v.apply[?T](v)
4402+
// Requiring the circular constraint `v <: ?T`,
4403+
// (because type parameter T occurs in v's type).
4404+
// So we create a fresh copy of the outer
4405+
// poly method type, so we now extend to:
4406+
// v.apply[?T'](v)
4407+
// Where `?T'` is a type var for a T' type parameter,
4408+
// leading to the non-circular `v <: ?T'` constraint.
4409+
//
4410+
// This also happens in `assignType(tree: untpd.TypeApply, ..)`
4411+
// to avoid any type arguments, containing the type lambda,
4412+
// being applied to the very same type lambda.
4413+
poly.newLikeThis(poly.paramNames, poly.paramInfos, poly.resType)
4414+
case _ => poly
4415+
case _ => poly
4416+
typeArgs = constrained(poly1, tree)._2.map(_.wrapInTypeTree(tree))
43954417
convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs)))
43964418
case wtp =>
43974419
val isStructuralCall = wtp.isValueType && isStructuralTermSelectOrApply(tree)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// A minimisation of interleaving-overload
2+
// Used while developing the tvar/tl clearnup in normalizedCompatible
3+
class B[U]
4+
class Test():
5+
def fn[T]: [U] => Int => B[U] = [U] => (x: Int) => new B[U]()
6+
def test(): Unit =
7+
fn(1)
8+
fn(2)
9+
()

tests/pos/zipped.min.scala

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Justifies the need for TypeApply in tryInsertImplicitOnQualifier
2+
// after failing ys.map[?B, C] using Zipped2's map
3+
// we want to try ys.map[?B] using Coll's map, after toColl
4+
final class Coll[+A]:
5+
def map[B](f: A => B): Coll[B] = new Coll[B]
6+
def lazyZip[B](that: Coll[B]): Zipped2[A, B] = new Zipped2[A, B](this, that)
7+
final class Zipped2[+X, +Y](xs: Coll[X], ys: Coll[Y]):
8+
def map[B, C](f: (X, Y) => B): Coll[C] = new Coll[C]
9+
object Zipped2:
10+
import scala.language.implicitConversions
11+
implicit def toColl[X, Y](zipped2: Zipped2[X, Y]): Coll[(X, Y)] = new Coll[(X, Y)]
12+
class Test:
13+
def test(xs: Coll[Int]): Unit =
14+
val ys = xs.lazyZip(xs)
15+
ys.map((x: (Int, Int)) => x._1 + x._2)

0 commit comments

Comments
 (0)