Skip to content

Commit 81e2e7f

Browse files
committed
Address review comments
1 parent c33be62 commit 81e2e7f

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

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

+13-11
Original file line numberDiff line numberDiff line change
@@ -4895,16 +4895,16 @@ object Types {
48954895
/** Instantiate variable with given type */
48964896
def instantiateWith(tp: Type)(using Context): Type = {
48974897
assert(tp ne this, i"self instantiation of $origin, constraint = ${ctx.typerState.constraint}")
4898-
if !myInst.exists then
4899-
typr.println(i"instantiating $this with $tp")
4898+
assert(!myInst.exists, i"$origin is already instantiated to $myInst but we attempted to instantiate it to $tp")
4899+
typr.println(i"instantiating $this with $tp")
49004900

4901-
if Config.checkConstraintsSatisfiable then
4902-
assert(currentEntry.bounds.contains(tp),
4903-
i"$origin is constrained to be $currentEntry but attempted to instantiate it to $tp")
4901+
if Config.checkConstraintsSatisfiable then
4902+
assert(currentEntry.bounds.contains(tp),
4903+
i"$origin is constrained to be $currentEntry but attempted to instantiate it to $tp")
49044904

4905-
if ((ctx.typerState eq owningState.nn.get.uncheckedNN) && !TypeComparer.subtypeCheckInProgress)
4906-
setInst(tp)
4907-
ctx.typerState.constraint = ctx.typerState.constraint.replace(origin, tp)
4905+
if ((ctx.typerState eq owningState.nn.get.uncheckedNN) && !TypeComparer.subtypeCheckInProgress)
4906+
setInst(tp)
4907+
ctx.typerState.constraint = ctx.typerState.constraint.replace(origin, tp)
49084908
tp
49094909
}
49104910

@@ -5811,11 +5811,13 @@ object Types {
58115811
protected def derivedLambdaType(tp: LambdaType)(formals: List[tp.PInfo], restpe: Type): Type =
58125812
tp.derivedLambdaType(tp.paramNames, formals, restpe)
58135813

5814+
protected def mapArg(arg: Type, tparam: ParamInfo): Type = arg match
5815+
case arg: TypeBounds => this(arg)
5816+
case arg => atVariance(variance * tparam.paramVarianceSign)(this(arg))
5817+
58145818
protected def mapArgs(args: List[Type], tparams: List[ParamInfo]): List[Type] = args match
58155819
case arg :: otherArgs if tparams.nonEmpty =>
5816-
val arg1 = arg match
5817-
case arg: TypeBounds => this(arg)
5818-
case arg => atVariance(variance * tparams.head.paramVarianceSign)(this(arg))
5820+
val arg1 = mapArg(arg, tparams.head)
58195821
val otherArgs1 = mapArgs(otherArgs, tparams.tail)
58205822
if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
58215823
else arg1 :: otherArgs1

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ object Inferencing {
165165
(using Context) extends TypeAccumulator[Boolean] {
166166

167167
/** Replace toplevel-covariant occurrences (i.e. covariant without double flips)
168-
* of Nothing by fresh type variables.
168+
* of Nothing by fresh type variables. Double-flips are not covered to be
169+
* conservative and save a bit of time on traversals; we could probably
170+
* generalize that if we see use cases.
169171
* For singleton types and references to module classes: try to
170172
* improve the widened type. For module classes, the widened type
171173
* is the intersection of all its non-transparent parent types.
@@ -191,6 +193,12 @@ object Inferencing {
191193
mapOver(t)
192194
else t
193195

196+
// Don't map Nothing arguments for higher-kinded types; we'd get the wrong kind */
197+
override def mapArg(arg: Type, tparam: ParamInfo): Type =
198+
if tparam.paramInfo.isLambdaSub then arg
199+
else super.mapArg(arg, tparam)
200+
end improve
201+
194202
/** Instantiate type variable with possibly improved computed instance type.
195203
* @return true if variable was instantiated with improved type, which
196204
* in this case should not be instantiated further, false otherwise.

tests/neg/foldinf-ill-kinded.check

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- [E007] Type Mismatch Error: tests/neg/foldinf-ill-kinded.scala:9:16 -------------------------------------------------
2+
9 | ys.combine(x) // error
3+
| ^^^^^^^^^^^^^
4+
| Found: Foo[List]
5+
| Required: Foo[Nothing]
6+
|
7+
| longer explanation available when compiling with `-explain`

tests/neg/foldinf-ill-kinded.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Foo[+T[_]]:
2+
def combine[T1[x] >: T[x]](x: T1[Int]): Foo[T1] = new Foo
3+
object Foo:
4+
def empty: Foo[Nothing] = new Foo
5+
6+
object X:
7+
def test(xs: List[List[Int]]): Unit =
8+
xs.foldLeft(Foo.empty)((ys, x) =>
9+
ys.combine(x) // error
10+
)

0 commit comments

Comments
 (0)