Skip to content

Commit 70e785f

Browse files
committed
Simplify result handling in FunProto.
Following the example of SelectionProto, we now always hide the result in a FunProto behind an IgnoreProto. This avoids a special case retry with a weaker FunProto in tryInsertApplyOrImplicit.
1 parent c70366d commit 70e785f

File tree

4 files changed

+14
-32
lines changed

4 files changed

+14
-32
lines changed

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ trait Applications extends Compatibility { self: Typer =>
441441
def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
442442

443443
def realApply(implicit ctx: Context): Tree = track("realApply") {
444-
var proto = new FunProto(tree.args, ignoreIfProto(pt), this)
444+
var proto = new FunProto(tree.args, IgnoredProto(pt), this)
445445
val fun1 = typedExpr(tree.fun, proto)
446446

447447
// Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as
@@ -461,7 +461,7 @@ trait Applications extends Compatibility { self: Typer =>
461461
val result = app.result
462462
ConstFold(result)
463463
} { (failedVal, failedState) =>
464-
val fun2 = tryInsertImplicits(fun1, proto)
464+
val fun2 = tryInsertImplicitOnQualifier(fun1, proto)
465465
if (fun1 eq fun2) {
466466
failedState.commit()
467467
failedVal

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ object ProtoTypes {
8383
override def deepenProto(implicit ctx: Context): Type = ignored
8484
}
8585

86-
def ignoreIfProto(tp: Type): Type = tp match {
87-
case proto: ProtoType => IgnoredProto(proto)
88-
case _ => tp
89-
}
90-
9186
/** A prototype for expressions [] that are part of a selection operation:
9287
*
9388
* [ ].name: proto

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

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,20 +1014,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
10141014
}
10151015
}
10161016

1017-
private def noResultProto(pt: Type) = pt match {
1018-
case pt: FunProto => pt.derivedFunProto(pt.args, WildcardType, pt.typer) // drop result type, because views are disabled
1019-
case _ => pt
1020-
}
1021-
1022-
/** Add apply node or implicit conversions. Three strategies are tried, and the first
1023-
* that is succesful is picked. If none of the strategies are succesful, continues with
1017+
/** Add apply node or implicit conversions. Two strategies are tried, and the first
1018+
* that is succesful is picked. If neither of the strategies are succesful, continues with
10241019
* `fallBack`.
10251020
*
10261021
* 1st strategy: Try to insert `.apply` so that the result conforms to prototype `pt`.
1027-
* 2nd strategy: If the expected type is a FunProto with a non-wildcard resulttype,
1028-
* try to match against the FunProto with wildcard resulttype (this allows for an additional
1029-
* implicit conversion on the result).
1030-
* 3rd stratgey: If tree is a select `qual.name`, try to insert an implicit conversion
1022+
* 2nd stratgey: If tree is a select `qual.name`, try to insert an implicit conversion
10311023
* around the qualifier part `qual` so that the result conforms to the expected type
10321024
* with wildcard result type.
10331025
*/
@@ -1036,23 +1028,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
10361028
val sel = typedSelect(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
10371029
if (sel.tpe.isError) sel else adapt(sel, pt)
10381030
} { (failedTree, failedState) =>
1039-
val tree1 = tryInsertImplicits(tree, pt)
1031+
val tree1 = tryInsertImplicitOnQualifier(tree, pt)
10401032
if (tree1 eq tree) fallBack(failedTree, failedState)
1041-
else adapt(tree1, noResultProto(pt))
1033+
else adapt(tree1, pt)
10421034
}
10431035

1044-
def tryInsertImplicits(tree: Tree, pt: ProtoType)(implicit ctx: Context): Tree = {
1045-
val normalizedProto = noResultProto(pt)
1046-
if (normalizedProto eq pt) tryInsertImplicitOnQualifier(tree, pt)
1047-
else tryEither { implicit ctx =>
1048-
val tree1 = adaptInterpolated(tree, normalizedProto, EmptyTree)
1049-
if (tree1 eq tree) ctx.error("no progress")
1050-
tree1
1051-
} { (_, _) =>
1052-
tryInsertImplicitOnQualifier(tree, normalizedProto)
1053-
}
1054-
}
1055-
10561036
/** If this tree is a select node `qual.name`, try to insert an implicit conversion
10571037
* `c` around `qual` so that `c(qual).name` conforms to `pt`. If that fails
10581038
* return `tree` itself.

tests/pos/resultGuidesInference.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object test {
2+
3+
def foo[T](x: T => T): Array[T] = ???
4+
5+
val x: Array[Int] = foo(x => x)
6+
7+
}

0 commit comments

Comments
 (0)