Skip to content

Commit ff284d4

Browse files
committed
Fix #5526: Better type inference for dependent function types
1 parent fcc35d2 commit ff284d4

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,9 @@ class Namer { typer: Typer =>
11571157
case TypeTree() =>
11581158
checkMembersOK(inferredType, mdef.pos)
11591159
case DependentTypeTree(tpFun) =>
1160-
tpFun(paramss.head)
1160+
val tpe = tpFun(paramss.head)
1161+
if (isFullyDefined(tpe, ForceDegree.none)) tpe
1162+
else typedAheadExpr(mdef.rhs, tpe).tpe
11611163
case TypedSplice(tpt: TypeTree) if !isFullyDefined(tpt.tpe, ForceDegree.none) =>
11621164
val rhsType = typedAheadExpr(mdef.rhs, tpt.tpe).tpe
11631165
mdef match {

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,10 @@ class Typer extends Namer
801801
val typeArgs = params1.map(_.tpt) :+ resTpt
802802
val tycon = TypeTree(funCls.typeRef)
803803
val core = assignType(cpy.AppliedTypeTree(tree)(tycon, typeArgs), tycon, typeArgs)
804-
val appMeth = ctx.newSymbol(ctx.owner, nme.apply, Synthetic | Deferred, mt)
804+
val appMeth = ctx.newSymbol(ctx.owner, nme.apply, Synthetic | Method | Deferred, mt, coord = body.pos)
805805
val appDef = assignType(
806806
untpd.DefDef(appMeth.name, Nil, List(params1), resultTpt, EmptyTree),
807-
appMeth)
807+
appMeth).withPos(body.pos)
808808
RefinedTypeTree(core, List(appDef), ctx.owner.asClass)
809809
}
810810

@@ -1233,7 +1233,9 @@ class Typer extends Namer
12331233
}
12341234
case _ =>
12351235
tree.withType(
1236-
if (isFullyDefined(pt, ForceDegree.none)) pt else UnspecifiedErrorType)
1236+
if (isFullyDefined(pt, ForceDegree.noBottom)) pt
1237+
else if (ctx.reporter.errorsReported) UnspecifiedErrorType
1238+
else errorType(i"cannot infer type; expected type $pt is not fully defined", tree.pos))
12371239
}
12381240
}
12391241

tests/pos/i5526a.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait A
2+
object test1 {
3+
def foo[E](f: (a: A) => (a.type, E)): E = {
4+
val a = new A {}
5+
f(a)._2
6+
}
7+
val res = foo { a => (a, 42) }
8+
val x: Int = res
9+
}
10+
object test2 {
11+
trait F[A, -E]
12+
def empty[A](value: A): F[A, Any] = ???
13+
def hof[R](f: (p: AnyRef) => F[R, p.type]): F[R, Any] = ???
14+
hof { p =>
15+
empty(42)
16+
}
17+
}

0 commit comments

Comments
 (0)